1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.mycore.restapi.v2;
20
21 import java.util.List;
22 import java.util.Optional;
23
24 import org.apache.logging.log4j.LogManager;
25 import org.apache.logging.log4j.Logger;
26
27 import jakarta.ws.rs.WebApplicationException;
28 import jakarta.ws.rs.core.Context;
29 import jakarta.ws.rs.core.MediaType;
30 import jakarta.ws.rs.core.Request;
31 import jakarta.ws.rs.core.Response;
32 import jakarta.ws.rs.core.Variant;
33 import jakarta.ws.rs.ext.ExceptionMapper;
34
35 public class MCRExceptionMapper implements ExceptionMapper<Exception> {
36
37 private final static List<Variant> SUPPORTED_VARIANTS = Variant
38 .mediaTypes(MediaType.APPLICATION_JSON_TYPE, MediaType.APPLICATION_XML_TYPE).build();
39
40 private final static Logger LOGGER = LogManager.getLogger();
41
42 @Context
43 Request request;
44
45 @Override
46 public Response toResponse(Exception exception) {
47 return Optional.ofNullable(request.selectVariant(SUPPORTED_VARIANTS))
48 .map(v -> fromException(exception))
49 .orElseGet(() -> (exception instanceof WebApplicationException)
50 ? ((WebApplicationException) exception).getResponse()
51 : null);
52 }
53
54 public static Response fromWebApplicationException(WebApplicationException wae) {
55 if (wae.getResponse().hasEntity()) {
56
57 LOGGER.warn("WebApplicationException already has an entity attached, forwarding response");
58 return wae.getResponse();
59 }
60 final Response response = getResponse(wae, wae.getResponse().getStatus());
61 response.getHeaders().putAll(wae.getResponse().getHeaders());
62 return response;
63 }
64
65 public static Response fromException(Exception e) {
66 if (e instanceof WebApplicationException) {
67 return fromWebApplicationException((WebApplicationException) e);
68 }
69 return getResponse(e, Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());
70 }
71
72 private static Response getResponse(Exception e, int statusCode) {
73 MCRErrorResponse response = MCRErrorResponse.fromStatus(statusCode)
74 .withCause(e)
75 .withMessage(e.getMessage())
76 .withDetail(Optional.of(e)
77 .map(ex -> (ex instanceof WebApplicationException) ? ex.getCause() : ex)
78 .map(Object::getClass)
79 .map(Class::getName)
80 .orElse(null));
81 LogManager.getLogger().error(response::getLogMessage, e);
82 return Response.status(response.getStatus())
83 .entity(response)
84 .build();
85 }
86 }