Skip to content
Snippets Groups Projects
Commit 2d0195b4 authored by OZGCloud's avatar OZGCloud
Browse files

Merge remote-tracking branch 'origin/master' into OZG-3328

parents 423b4e47 8d546108
No related branches found
No related tags found
No related merge requests found
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
</parent> </parent>
<groupId>de.ozgcloud</groupId> <groupId>de.ozgcloud</groupId>
<artifactId>administration</artifactId> <artifactId>administration</artifactId>
<version>0.4.0-SNAPSHOT</version> <version>0.5.0-SNAPSHOT</version>
<name>Administration</name> <name>Administration</name>
<description>Administration Backend Project</description> <description>Administration Backend Project</description>
......
...@@ -29,62 +29,70 @@ import java.util.Map; ...@@ -29,62 +29,70 @@ import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import org.springframework.data.rest.webmvc.ResourceNotFoundException; import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ProblemDetail; import org.springframework.http.ProblemDetail;
import org.springframework.security.access.AccessDeniedException; import org.springframework.security.access.AccessDeniedException;
import org.springframework.web.ErrorResponse;
import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
import de.ozgcloud.common.errorhandling.TechnicalException; import de.ozgcloud.common.errorhandling.TechnicalException;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
@RestControllerAdvice @RestControllerAdvice
public class ExceptionController extends ResponseEntityExceptionHandler { public class ExceptionController extends ResponseEntityExceptionHandler {
@ExceptionHandler(RuntimeException.class) @ExceptionHandler(RuntimeException.class)
public ErrorResponse handleRuntimeException(RuntimeException ex) { @ResponseBody
return ErrorResponse.builder(ex, HttpStatus.INTERNAL_SERVER_ERROR, ex.getLocalizedMessage()).build(); public ProblemDetail handleRuntimeException(RuntimeException ex) {
return buildProblemDetail(HttpStatus.INTERNAL_SERVER_ERROR, ex);
} }
@ExceptionHandler(AccessDeniedException.class) @ExceptionHandler(AccessDeniedException.class)
public ErrorResponse handleAccessDeniedException(AccessDeniedException ex) { @ResponseBody
return ErrorResponse.builder(ex, HttpStatus.FORBIDDEN, ex.getLocalizedMessage()).build(); public ProblemDetail handleAccessDeniedException(AccessDeniedException ex) {
return buildProblemDetail(HttpStatus.FORBIDDEN, ex);
} }
@ExceptionHandler(ResourceNotFoundException.class) @ExceptionHandler(ResourceNotFoundException.class)
public ErrorResponse handleResourceNotFoundException(ResourceNotFoundException ex) { @ResponseBody
return ErrorResponse.builder(ex, HttpStatus.NOT_FOUND, ex.getLocalizedMessage()).build(); public ProblemDetail handleResourceNotFoundException(ResourceNotFoundException ex) {
return buildProblemDetail(HttpStatus.NOT_FOUND, ex);
} }
@ExceptionHandler(FunctionalException.class) @ExceptionHandler(FunctionalException.class)
public ErrorResponse handleFunctionalException(FunctionalException ex) { @ResponseBody
return ErrorResponse.builder(ex, HttpStatus.BAD_REQUEST, ex.getLocalizedMessage()).build(); public ProblemDetail handleFunctionalException(FunctionalException ex) {
return buildProblemDetail(HttpStatus.BAD_REQUEST, ex);
} }
@ExceptionHandler(TechnicalException.class) @ExceptionHandler(TechnicalException.class)
public ErrorResponse handleTechnicalException(TechnicalException ex) { @ResponseBody
return ErrorResponse.builder(ex, HttpStatus.INTERNAL_SERVER_ERROR, ex.getLocalizedMessage()).build(); public ProblemDetail handleTechnicalException(TechnicalException ex) {
return buildProblemDetail(HttpStatus.INTERNAL_SERVER_ERROR, ex);
}
private ProblemDetail buildProblemDetail(HttpStatus status, Exception ex) {
return ProblemDetail.forStatusAndDetail(status, ex.getLocalizedMessage());
} }
@ExceptionHandler(ConstraintViolationException.class) @ExceptionHandler(ConstraintViolationException.class)
public ErrorResponse handleConstraintViolationException(ConstraintViolationException ex) { @ResponseBody
var problemDetail = buildProblemDetail(HttpStatus.UNPROCESSABLE_ENTITY, ex); public ProblemDetail handleConstraintViolationException(ConstraintViolationException ex) {
return ErrorResponse.builder(ex, problemDetail).build(); return buildConstraintViolationProblemDetail(HttpStatus.UNPROCESSABLE_ENTITY, ex);
} }
private ProblemDetail buildProblemDetail(HttpStatus status, ConstraintViolationException ex) { private ProblemDetail buildConstraintViolationProblemDetail(HttpStatus status, ConstraintViolationException ex) {
var problemDetail = ProblemDetail.forStatusAndDetail(status, ex.getLocalizedMessage()); var problemDetail = ProblemDetail.forStatusAndDetail(status, ex.getLocalizedMessage());
problemDetail.setProperty("invalid-params", getDetailedviolationList(ex.getConstraintViolations())); problemDetail.setProperty("invalid-params", getDetailedviolationList(ex.getConstraintViolations()));
return problemDetail; return problemDetail;
} }
private List<Map<String, String>> getDetailedviolationList(Set<ConstraintViolation<?>> violations) { private List<Map<String, String>> getDetailedviolationList(Set<ConstraintViolation<?>> violations) {
List<Map<String, String>> detailedViolations = new ArrayList<>(); var detailedViolations = new ArrayList<Map<String, String>>();
Optional.ofNullable(violations).orElse(Collections.emptySet()).forEach(v -> detailedViolations.add(buildDetailedViolation(v))); Optional.ofNullable(violations).orElse(Collections.emptySet()).forEach(v -> detailedViolations.add(buildDetailedViolation(v)));
return detailedViolations; return detailedViolations;
......
...@@ -6,7 +6,6 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder ...@@ -6,7 +6,6 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import java.util.Set; import java.util.Set;
import java.util.stream.Stream;
import jakarta.validation.ConstraintViolation; import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException; import jakarta.validation.ConstraintViolationException;
...@@ -18,13 +17,9 @@ import org.apache.commons.lang3.StringUtils; ...@@ -18,13 +17,9 @@ import org.apache.commons.lang3.StringUtils;
import org.assertj.core.util.Arrays; import org.assertj.core.util.Arrays;
import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.HttpStatus;
import org.springframework.security.test.context.support.WithMockUser; import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.ResultActions;
...@@ -47,38 +42,9 @@ class ExceptionControllerITCase { ...@@ -47,38 +42,9 @@ class ExceptionControllerITCase {
@MockBean @MockBean
private RootModelAssembler modelAssembler; private RootModelAssembler modelAssembler;
@Nested
class TestExceptions {
@ParameterizedTest
@MethodSource("exceptionAndExpectedStatus")
@SneakyThrows
void shouldHandleExceptionWithStatus(Class<? extends Exception> exceptionClass, HttpStatus expectedStatus) {
when(modelAssembler.toModel(any())).thenThrow(TestErrorController.EXCEPTION_PRODUCER.get(exceptionClass).produceException());
var result = performGet();
result.andExpect(status().is(expectedStatus.value()));
}
@ParameterizedTest
@MethodSource("exceptionAndExpectedStatus")
@SneakyThrows
void shouldRespondWithStatusInBody(Class<? extends Exception> exceptionClass, HttpStatus expectedStatus) {
when(modelAssembler.toModel(any())).thenThrow(exceptionClass);
var result = performGet();
result.andExpect(jsonPath("$.status").value(expectedStatus.value()));
}
private static Stream<Arguments> exceptionAndExpectedStatus() {
return TestErrorController.STATUS_BY_EXCEPTION.entrySet().stream().map(kv -> Arguments.of(kv.getKey(), kv.getValue()));
}
}
@Nested @Nested
class TestConstraintViolationException { class TestConstraintViolationException {
@Test @Test
@SneakyThrows @SneakyThrows
void shouldHaveInvalidFieldNameInResponse() { void shouldHaveInvalidFieldNameInResponse() {
...@@ -129,11 +95,9 @@ class ExceptionControllerITCase { ...@@ -129,11 +95,9 @@ class ExceptionControllerITCase {
private String string2; private String string2;
} }
}
@SneakyThrows @SneakyThrows
private ResultActions performGet() { private ResultActions performGet() {
return mockMvc.perform(get(RootController.PATH)); return mockMvc.perform(get(RootController.PATH));
} }
}
} }
\ No newline at end of file
...@@ -21,23 +21,27 @@ ...@@ -21,23 +21,27 @@
*/ */
package de.ozgcloud.admin.common.errorhandling; package de.ozgcloud.admin.common.errorhandling;
import static org.junit.Assert.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import java.util.stream.Stream;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest; import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.jayway.jsonpath.JsonPath;
import de.ozgcloud.common.errorhandling.TechnicalException;
import lombok.SneakyThrows; import lombok.SneakyThrows;
class ExceptionControllerTest { class ExceptionControllerTest {
...@@ -51,97 +55,392 @@ class ExceptionControllerTest { ...@@ -51,97 +55,392 @@ class ExceptionControllerTest {
.setControllerAdvice(new ExceptionController()).build(); .setControllerAdvice(new ExceptionController()).build();
} }
@DisplayName("Error handler") @DisplayName("Runtime Exception")
@Nested @Nested
class TestErrorHandler { class TestRuntimeException {
private final static String TEST_ERROR_ENDPOINT = TestErrorController.BASE_PATH + "/runtime";
private final static int STATUS_VALUE = HttpStatus.INTERNAL_SERVER_ERROR.value();
@ParameterizedTest
@MethodSource("exceptionAndExpectedStatus")
@SneakyThrows @SneakyThrows
void shouldHandleExceptionWithStatus(Class<? extends Exception> exceptionClass, HttpStatus expectedStatus) { @Test
var result = doPerformWithError(exceptionClass); void shouldReturnStatus() {
var result = doPerformGet();
result.andExpect(status().is(expectedStatus.value())); result.andExpect(status().is(STATUS_VALUE));
} }
@ParameterizedTest @DisplayName("response body")
@MethodSource("exceptionAndExpectedStatus") @Nested
class TestRuntimeExceptionBody {
@SneakyThrows @SneakyThrows
void shouldRespondWithStatusInBody(Class<? extends Exception> exceptionClass, HttpStatus expectedStatus) { @Test
var result = doPerformWithError(exceptionClass); void shouldHaveStatus() {
var result = doPerformGet();
result.andExpect(jsonPath("$.status").value(expectedStatus.value())); result.andExpect(jsonPath("$.status").value(STATUS_VALUE));
} }
@ParameterizedTest
@MethodSource("exceptionAndExpectedStatus")
@SneakyThrows @SneakyThrows
void shouldRespondWithTitler(Class<? extends Exception> exceptionClass, HttpStatus expectedStatus) { @Test
var result = doPerformWithError(exceptionClass); void shouldHaveTitle() {
var result = doPerformGet();
result.andExpect(jsonPath("$.title").exists()); result.andExpect(jsonPath("$.title").value("Internal Server Error"));
} }
@ParameterizedTest
@MethodSource("exceptionAndExpectedStatus")
@SneakyThrows @SneakyThrows
void shouldRespondWithDetail(Class<? extends Exception> exceptionClass, HttpStatus expectedStatus) { @Test
var result = doPerformWithError(exceptionClass); void shouldHaveDetail() {
var result = doPerformGet();
result.andExpect(jsonPath("$.detail").exists()); result.andExpect(jsonPath("$.detail").value("error message"));
} }
@ParameterizedTest
@MethodSource("exceptionAndExpectedStatus")
@SneakyThrows @SneakyThrows
void shouldRespondWithInstance(Class<? extends Exception> exceptionClass, HttpStatus expectedStatus) { @Test
var result = doPerformWithError(exceptionClass); void shouldHaveInstance() {
var result = doPerformGet();
result.andExpect(jsonPath("$.instance").exists()); result.andExpect(jsonPath("$.instance").value(TEST_ERROR_ENDPOINT));
} }
@ParameterizedTest
@MethodSource("exceptionAndExpectedStatus")
@SneakyThrows @SneakyThrows
void shouldRespondWithType(Class<? extends Exception> exceptionClass, HttpStatus expectedStatus) { void shouldHaveType() {
var result = doPerformWithError(exceptionClass); var result = doPerformGet();
result.andExpect(jsonPath("$.type").exists()); result.andExpect(jsonPath("$.type").value("about:blank"));
}
} }
private static Stream<Arguments> exceptionAndExpectedStatus() { @SneakyThrows
return TestErrorController.STATUS_BY_EXCEPTION.entrySet().stream().map(kv -> Arguments.of(kv.getKey(), kv.getValue())); private ResultActions doPerformGet() {
return mockMvc.perform(get(TEST_ERROR_ENDPOINT));
}
} }
@DisplayName("Access Denied Exception")
@Nested
class TestAccessDeniedException {
private final static String TEST_ERROR_ENDPOINT = TestErrorController.BASE_PATH + "/access-denied";
private final static int STATUS_VALUE = HttpStatus.FORBIDDEN.value();
@SneakyThrows @SneakyThrows
private ResultActions doPerformWithError(Class<? extends Exception> exceptionClass) { @Test
return mockMvc.perform(get("/api/test-error").param("errorClassName", exceptionClass.getName())); void shouldReturnStatus() {
var result = doPerformGet();
result.andExpect(status().is(STATUS_VALUE));
} }
@DisplayName("response body")
@Nested
class TestAccessDeniedExceptionBody {
@SneakyThrows
@Test
void shouldHaveStatus() {
var result = doPerformGet();
result.andExpect(jsonPath("$.status").value(STATUS_VALUE));
}
@SneakyThrows
@Test
void shouldHaveTitle() {
var result = doPerformGet();
result.andExpect(jsonPath("$.title").value("Forbidden"));
}
@SneakyThrows
@Test
void shouldHaveDetail() {
var result = doPerformGet();
result.andExpect(jsonPath("$.detail").value("error message"));
} }
@DisplayName("ResourceNotFound error") @SneakyThrows
@Test
void shouldHaveInstance() {
var result = doPerformGet();
result.andExpect(jsonPath("$.instance").value(TEST_ERROR_ENDPOINT));
}
@SneakyThrows
void shouldHaveType() {
var result = doPerformGet();
result.andExpect(jsonPath("$.type").value("about:blank"));
}
}
@SneakyThrows
private ResultActions doPerformGet() {
return mockMvc.perform(get(TEST_ERROR_ENDPOINT));
}
}
@DisplayName("ResourceNotFound Exception")
@Nested @Nested
class TestResourceNotFoundError { class TestResourceNotFoundException {
private final static String TEST_ERROR_ENDPOINT = TestErrorController.BASE_PATH + "/resource-not-found";
private final static int STATUS_VALUE = HttpStatus.NOT_FOUND.value();
@SneakyThrows
@Test @Test
void shouldReturnStatus() {
var result = doPerformGet();
result.andExpect(status().is(STATUS_VALUE));
}
@DisplayName("response body")
@Nested
class TestResourceNotFoundExceptionBody {
@SneakyThrows @SneakyThrows
@Test
void shouldHaveStatus() { void shouldHaveStatus() {
var result = doRequestUnknown(); var result = doPerformGet();
result.andExpect(status().is(HttpStatus.NOT_FOUND.value())); result.andExpect(jsonPath("$.status").value(STATUS_VALUE));
} }
@SneakyThrows
@Test @Test
void shouldHaveTitle() {
var result = doPerformGet();
result.andExpect(jsonPath("$.title").value("Not Found"));
}
@SneakyThrows
@Test
void shouldHaveDetail() {
var result = doPerformGet();
result.andExpect(jsonPath("$.detail").value("error message"));
}
@SneakyThrows
@Test
void shouldHaveInstance() {
var result = doPerformGet();
result.andExpect(jsonPath("$.instance").value(TEST_ERROR_ENDPOINT));
}
@SneakyThrows @SneakyThrows
void shouldRespondWithStatusInBody() { void shouldHaveType() {
var result = doRequestUnknown(); var result = doPerformGet();
result.andExpect(jsonPath("$.type").value("about:blank"));
}
}
result.andExpect(jsonPath("$.status").value(HttpStatus.NOT_FOUND.value())); @SneakyThrows
private ResultActions doPerformGet() {
return mockMvc.perform(get(TEST_ERROR_ENDPOINT));
} }
}
@DisplayName("Functional Exception")
@Nested
class TestFunctionalException {
private final static String TEST_ERROR_ENDPOINT = TestErrorController.BASE_PATH + "/functional";
private final static int STATUS_VALUE = HttpStatus.BAD_REQUEST.value();
@SneakyThrows @SneakyThrows
private ResultActions doRequestUnknown() { @Test
return mockMvc.perform(get("/api/unknown")); void shouldReturnStatus() {
var result = doPerformGet();
result.andExpect(status().is(STATUS_VALUE));
} }
@DisplayName("response body")
@Nested
class TestFunctionalExceptionBody {
@SneakyThrows
@Test
void shouldHaveStatus() {
var result = doPerformGet();
result.andExpect(jsonPath("$.status").value(STATUS_VALUE));
}
@SneakyThrows
@Test
void shouldHaveTitle() {
var result = doPerformGet();
result.andExpect(jsonPath("$.title").value("Bad Request"));
}
@DisplayName("detail")
@Nested
class TestBodyDetail {
@SneakyThrows
@Test
void shouldContainErrorMessage() {
var result = doPerformGet();
assertTrue(getDetailFromResponseContent(result).contains("Functional error: error message"));
}
@SneakyThrows
@Test
void shouldContainExceptionId() {
var result = doPerformGet();
assertTrue(getDetailFromResponseContent(result).contains("(ExceptionId: "));
}
}
@SneakyThrows
@Test
void shouldHaveInstance() {
var result = doPerformGet();
result.andExpect(jsonPath("$.instance").value(TEST_ERROR_ENDPOINT));
}
@SneakyThrows
void shouldHaveType() {
var result = doPerformGet();
result.andExpect(jsonPath("$.type").value("about:blank"));
}
}
@SneakyThrows
private ResultActions doPerformGet() {
return mockMvc.perform(get(TEST_ERROR_ENDPOINT));
}
}
@DisplayName("TechnicalException")
@Nested
class TestTechnicalException {
private final static String TEST_ERROR_ENDPOINT = TestErrorController.BASE_PATH + "/technical";
private final static int STATUS_VALUE = HttpStatus.INTERNAL_SERVER_ERROR.value();
@SneakyThrows
@Test
void shouldReturnStatus() {
var result = doPerformGet();
result.andExpect(status().is(STATUS_VALUE));
}
@DisplayName("response body")
@Nested
class TestTechnicalExceptionBody {
@SneakyThrows
@Test
void shouldHaveStatus() {
var result = doPerformGet();
result.andExpect(jsonPath("$.status").value(STATUS_VALUE));
}
@SneakyThrows
@Test
void shouldHaveTitle() {
var result = doPerformGet();
result.andExpect(jsonPath("$.title").value("Internal Server Error"));
}
@DisplayName("detail")
@Nested
class TestBodyDetail {
@SneakyThrows
@Test
void shouldContainErrorMessage() {
var result = doPerformGet();
assertTrue(getDetailFromResponseContent(result).contains("error message"));
}
@SneakyThrows
@Test
void shouldContainExceptionId() {
var result = doPerformGet();
assertTrue(getDetailFromResponseContent(result).contains("(ExceptionId: "));
}
}
@SneakyThrows
@Test
void shouldHaveInstance() {
var result = doPerformGet();
result.andExpect(jsonPath("$.instance").value(TEST_ERROR_ENDPOINT));
}
@SneakyThrows
void shouldHaveType() {
var result = doPerformGet();
result.andExpect(jsonPath("$.type").value("about:blank"));
}
}
@SneakyThrows
private ResultActions doPerformGet() {
return mockMvc.perform(get(TEST_ERROR_ENDPOINT));
}
}
@SneakyThrows
private String getDetailFromResponseContent(ResultActions resultActions) {
return JsonPath.read(resultActions.andReturn().getResponse().getContentAsString(), "$.detail");
}
}
@RestController
@RequestMapping(TestErrorController.BASE_PATH)
class TestErrorController {
public final static String BASE_PATH = "/api/test-error";
static final String ERROR_MESSAGE = "error message";
@GetMapping("/runtime")
String throwRuntimeException() throws Exception {
throw new RuntimeException(ERROR_MESSAGE);
}
@GetMapping("/access-denied")
String throwAccessException() throws Exception {
throw new AccessDeniedException(ERROR_MESSAGE);
}
@GetMapping("/resource-not-found")
String throwResourceNotFoundException() throws Exception {
throw new ResourceNotFoundException(ERROR_MESSAGE);
}
@GetMapping("/functional")
String throwFunctionalExceptionException() throws Exception {
throw new FunctionalException(() -> ERROR_MESSAGE);
}
@GetMapping("/technical")
String throwTechnicalExceptionException() throws Exception {
throw new TechnicalException(ERROR_MESSAGE);
} }
} }
\ No newline at end of file
/*
* Copyright (c) 2024. Das Land Schleswig-Holstein vertreten durch das Ministerium für Energiewende, Klimaschutz, Umwelt und Natur
* Zentrales IT-Management
*
* Lizenziert unter der EUPL, Version 1.2 oder - sobald
* diese von der Europäischen Kommission genehmigt wurden -
* Folgeversionen der EUPL ("Lizenz");
* Sie dürfen dieses Werk ausschließlich gemäß
* dieser Lizenz nutzen.
* Eine Kopie der Lizenz finden Sie hier:
*
* https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
*
* Sofern nicht durch anwendbare Rechtsvorschriften
* gefordert oder in schriftlicher Form vereinbart, wird
* die unter der Lizenz verbreitete Software "so wie sie
* ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
* ausdrücklich oder stillschweigend - verbreitet.
* Die sprachspezifischen Genehmigungen und Beschränkungen
* unter der Lizenz sind dem Lizenztext zu entnehmen.
*/
package de.ozgcloud.admin.common.errorhandling;
import java.util.Collections;
import java.util.Map;
import jakarta.validation.ConstraintViolationException;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import de.ozgcloud.common.errorhandling.TechnicalException;
@RestController
@RequestMapping("/api/test-error")
class TestErrorController {
@FunctionalInterface
interface ExceptionProducer {
Exception produceException();
}
static final Map<Class<? extends Exception>, HttpStatus> STATUS_BY_EXCEPTION = Map.of(
RuntimeException.class, HttpStatus.INTERNAL_SERVER_ERROR,
AccessDeniedException.class, HttpStatus.FORBIDDEN,
ConstraintViolationException.class, HttpStatus.UNPROCESSABLE_ENTITY,
ResourceNotFoundException.class, HttpStatus.NOT_FOUND,
FunctionalException.class, HttpStatus.BAD_REQUEST,
TechnicalException.class, HttpStatus.INTERNAL_SERVER_ERROR);
static final String ERROR_MESSAGE = "error message";
static Map<Class<? extends Exception>, ExceptionProducer> EXCEPTION_PRODUCER = Map.of(
RuntimeException.class, () -> new RuntimeException(ERROR_MESSAGE),
AccessDeniedException.class, () -> new AccessDeniedException(ERROR_MESSAGE),
ConstraintViolationException.class, () -> new ConstraintViolationException(ERROR_MESSAGE, Collections.emptySet()),
ResourceNotFoundException.class, () -> new ResourceNotFoundException(ERROR_MESSAGE),
FunctionalException.class, () -> new FunctionalException(() -> ERROR_MESSAGE),
TechnicalException.class, () -> new TechnicalException(ERROR_MESSAGE));
@GetMapping
String throwException(@RequestParam String errorClassName) throws Exception {
throw EXCEPTION_PRODUCER.get(
Class.forName(errorClassName)).produceException();
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment