1 package common.http.error;
2
3 import common.http.interceptor.HttpServletBiConsumer;
4 import common.http.interceptor.ServletInterceptor;
5 import usecase.auth.AuthenticationRequiredException;
6 import usecase.auth.AuthorizationException;
7 import usecase.auth.BannedUserException;
8
9 import javax.json.Json;
10 import javax.json.JsonObject;
11 import javax.servlet.ServletException;
12 import javax.servlet.http.HttpServletRequest;
13 import javax.servlet.http.HttpServletResponse;
14 import javax.validation.ConstraintViolation;
15 import javax.validation.ConstraintViolationException;
16 import java.io.IOException;
17 import java.io.PrintWriter;
18 import java.time.format.DateTimeFormatter;
19 import java.util.Collection;
20 import java.util.Collections;
21 import java.util.List;
22 import java.util.stream.Collectors;
23
24 import static javax.servlet.http.HttpServletResponse.*;
25
26
27
28
29 public class JSONErrorInterceptor extends ServletInterceptor<JSONError> {
30
31 @Override
32 protected void init(JSONError annotation) {
33
34 }
35
36 @Override
37 public void handle(HttpServletRequest req, HttpServletResponse resp, HttpServletBiConsumer next) throws ServletException, IOException {
38 try{
39 next.handle(req,resp);
40 } catch (IllegalArgumentException e) {
41 sendJSONError(resp, SC_BAD_REQUEST, e.getMessage());
42 } catch (ConstraintViolationException e) {
43 List<String> collect = e.getConstraintViolations().stream()
44 .map(ConstraintViolation::getMessage)
45 .collect(Collectors.toList());
46
47 sendJSONError(resp,SC_BAD_REQUEST,collect);
48 } catch (AuthenticationRequiredException e) {
49 sendJSONError(resp,SC_UNAUTHORIZED, e.getMessage());
50 } catch (BannedUserException e){
51 if (e.getDuration() != null){
52 String end = DateTimeFormatter.ISO_INSTANT.format(e.getDuration());
53 sendJSONError(resp,SC_FORBIDDEN, "Sei bannato fino a " + end);
54 } else {
55 sendJSONError(resp, SC_FORBIDDEN);
56 }
57 } catch (AuthorizationException e) {
58 sendJSONError(resp,SC_FORBIDDEN, e.getMessage());
59 } catch (RuntimeException | ServletException | IOException e){
60 sendJSONError(resp,SC_INTERNAL_SERVER_ERROR, "Internal server error");
61 req.getServletContext().log(e.getMessage(), e);
62 }
63 }
64
65 private void sendJSONError(HttpServletResponse resp, int code, Collection<String> messages) throws IOException {
66 JsonObject errors = Json.createObjectBuilder().add("errors", Json.createArrayBuilder(messages)).build();
67 resp.setStatus(code);
68 resp.setContentType("application/json");
69 PrintWriter writer = resp.getWriter();
70 writer.print(errors.toString());
71 writer.flush();
72
73 }
74
75 private void sendJSONError(HttpServletResponse resp, int code, String message) throws IOException {
76 List<String> singleton = message == null ? Collections.emptyList() : List.of(message);
77 sendJSONError(resp, code, singleton);
78 }
79
80 private void sendJSONError(HttpServletResponse resp, int code) throws IOException{
81 sendJSONError(resp,code,Collections.emptyList());
82 }
83
84 @Override
85 public int priority() {
86 return 2;
87 }
88 }