1 package de.juplo.kafka.chat.backend.api;
3 import de.juplo.kafka.chat.backend.domain.InvalidUsernameException;
4 import de.juplo.kafka.chat.backend.domain.MessageMutationException;
5 import de.juplo.kafka.chat.backend.domain.ShardNotOwnedException;
6 import de.juplo.kafka.chat.backend.domain.UnknownChatroomException;
7 import org.springframework.beans.factory.annotation.Value;
8 import org.springframework.http.HttpStatus;
9 import org.springframework.http.ProblemDetail;
10 import org.springframework.web.bind.annotation.ControllerAdvice;
11 import org.springframework.web.bind.annotation.ExceptionHandler;
12 import org.springframework.web.server.ServerWebExchange;
13 import org.springframework.web.util.UriComponentsBuilder;
15 import java.util.Date;
19 public class ChatBackendControllerAdvice
21 @Value("${server.context-path:/}")
24 @ExceptionHandler(UnknownChatroomException.class)
25 public final ProblemDetail handleException(
26 UnknownChatroomException e,
27 ServerWebExchange exchange,
28 UriComponentsBuilder uriComponentsBuilder)
30 final HttpStatus status = HttpStatus.NOT_FOUND;
31 ProblemDetail problem = ProblemDetail.forStatus(status);
33 problem.setProperty("timestamp", new Date());
35 problem.setProperty("requestId", exchange.getRequest().getId());
37 problem.setType(uriComponentsBuilder.replacePath(contextPath).path("/problem/unknown-chatroom").build().toUri());
38 StringBuilder stringBuilder = new StringBuilder();
39 stringBuilder.append(status.getReasonPhrase());
40 stringBuilder.append(" - ");
41 stringBuilder.append(e.getMessage());
42 problem.setTitle(stringBuilder.toString());
44 stringBuilder.setLength(0);
45 stringBuilder.append("Chatroom unknown: ");
46 stringBuilder.append(e.getChatroomId());
47 problem.setDetail(stringBuilder.toString());
49 problem.setProperty("chatroomId", e.getChatroomId());
54 @ExceptionHandler(ShardNotOwnedException.class)
55 public final ProblemDetail handleException(
56 ShardNotOwnedException e,
57 ServerWebExchange exchange,
58 UriComponentsBuilder uriComponentsBuilder)
60 final HttpStatus status = HttpStatus.NOT_FOUND;
61 ProblemDetail problem = ProblemDetail.forStatus(status);
63 problem.setProperty("timestamp", new Date());
65 problem.setProperty("requestId", exchange.getRequest().getId());
67 problem.setType(uriComponentsBuilder.replacePath(contextPath).path("/problem/shard-not-owned").build().toUri());
68 StringBuilder stringBuilder = new StringBuilder();
69 stringBuilder.append(status.getReasonPhrase());
70 stringBuilder.append(" - ");
71 stringBuilder.append(e.getMessage());
72 problem.setTitle(stringBuilder.toString());
74 stringBuilder.setLength(0);
75 stringBuilder.append("Shard not owned: ");
76 stringBuilder.append(e.getShard());
77 problem.setDetail(stringBuilder.toString());
79 problem.setProperty("shard", e.getShard());
84 @ExceptionHandler(MessageMutationException.class)
85 public final ProblemDetail handleException(
86 MessageMutationException e,
87 ServerWebExchange exchange,
88 UriComponentsBuilder uriComponentsBuilder)
90 final HttpStatus status = HttpStatus.BAD_REQUEST;
91 ProblemDetail problem = ProblemDetail.forStatus(status);
93 problem.setProperty("timestamp", new Date());
95 problem.setProperty("requestId", exchange.getRequest().getId());
97 problem.setType(uriComponentsBuilder.replacePath(contextPath).path("/problem/message-mutation").build().toUri());
98 StringBuilder stringBuilder = new StringBuilder();
99 stringBuilder.append(status.getReasonPhrase());
100 stringBuilder.append(" - ");
101 stringBuilder.append(e.getMessage());
102 problem.setTitle(stringBuilder.toString());
104 stringBuilder.setLength(0);
105 stringBuilder.append("The existing message with user=");
106 stringBuilder.append(e.getExisting().getUsername());
107 stringBuilder.append(" and id=");
108 stringBuilder.append(e.getExisting().getId());
109 stringBuilder.append(" cannot be mutated!");
110 problem.setDetail(stringBuilder.toString());
112 problem.setProperty("existingMessage", MessageTo.from(e.getExisting()));
114 problem.setProperty("mutatedText", e.getMutatedText());
119 @ExceptionHandler(InvalidUsernameException.class)
120 public final ProblemDetail handleException(
121 InvalidUsernameException e,
122 ServerWebExchange exchange,
123 UriComponentsBuilder uriComponentsBuilder)
125 final HttpStatus status = HttpStatus.BAD_REQUEST;
126 ProblemDetail problem = ProblemDetail.forStatus(status);
128 problem.setProperty("timestamp", new Date());
130 problem.setProperty("requestId", exchange.getRequest().getId());
132 problem.setType(uriComponentsBuilder.replacePath(contextPath).path("/problem/invalid-username").build().toUri());
133 StringBuilder stringBuilder = new StringBuilder();
134 stringBuilder.append(status.getReasonPhrase());
135 stringBuilder.append(" - ");
136 stringBuilder.append(e.getMessage());
137 problem.setTitle(stringBuilder.toString());
139 stringBuilder.setLength(0);
140 stringBuilder.append("Invalid username: ");
141 stringBuilder.append(e.getUsername());
142 stringBuilder.append(
143 "! A valid username must consist of at at least two letters and " +
144 "must only contain lower case letters a-z, numbers and dashes");
145 problem.setDetail(stringBuilder.toString());
147 problem.setProperty("username", e.getUsername());