1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.bremersee.exception;
18
19 import static java.util.Objects.isNull;
20
21 import java.io.Serial;
22 import lombok.EqualsAndHashCode;
23 import lombok.Getter;
24
25
26
27
28
29
30 @EqualsAndHashCode(callSuper = true)
31 public class ServiceException extends RuntimeException
32 implements ErrorCodeAware, HttpStatusAware {
33
34 @Serial
35 private static final long serialVersionUID = 2L;
36
37
38
39
40 public static final String ERROR_CODE_ALREADY_EXISTS = "COMMON:ALREADY_EXISTS";
41
42
43
44
45 private final int httpStatus;
46
47
48
49
50 @Getter
51 private final String errorCode;
52
53
54
55
56 protected ServiceException() {
57 super();
58 this.httpStatus = 0;
59 this.errorCode = null;
60 }
61
62
63
64
65
66
67
68 protected ServiceException(int httpStatus, String errorCode) {
69 super();
70 this.httpStatus = httpStatus;
71 this.errorCode = errorCode;
72 }
73
74
75
76
77
78
79
80
81 protected ServiceException(int httpStatus, String errorCode, String reason) {
82 super(reason);
83 this.httpStatus = httpStatus;
84 this.errorCode = errorCode;
85 }
86
87
88
89
90
91
92
93
94 protected ServiceException(int httpStatus, String errorCode, Throwable cause) {
95 super(cause);
96 this.httpStatus = httpStatus;
97 this.errorCode = errorCode;
98 }
99
100
101
102
103
104
105
106
107
108 protected ServiceException(
109 int httpStatus,
110 String errorCode,
111 String reason,
112 Throwable cause) {
113 super(reason, cause);
114 this.httpStatus = httpStatus;
115 this.errorCode = errorCode;
116 }
117
118
119
120
121
122
123 @Override
124 public int status() {
125 return httpStatus;
126 }
127
128
129
130
131
132
133 public static ServiceException internalServerError() {
134 return internalServerError(null);
135 }
136
137
138
139
140
141
142
143 public static ServiceException internalServerError(String reason) {
144 return internalServerError(reason, (String) null);
145 }
146
147
148
149
150
151
152
153
154 public static ServiceException internalServerError(String reason, Throwable cause) {
155 return internalServerError(reason, null, cause);
156 }
157
158
159
160
161
162
163
164
165 public static ServiceException internalServerError(String reason, String errorCode) {
166 return internalServerError(reason, errorCode, null);
167 }
168
169
170
171
172
173
174
175
176
177 public static ServiceException internalServerError(
178 String reason,
179 String errorCode,
180 Throwable cause) {
181 return ServiceException.builder()
182 .httpStatus(500)
183 .reason(reason)
184 .errorCode(errorCode)
185 .cause(cause)
186 .build();
187 }
188
189
190
191
192
193
194
195 public static ServiceException badRequest() {
196 return badRequest(null);
197 }
198
199
200
201
202
203
204
205 public static ServiceException badRequest(String reason) {
206 return badRequest(reason, (String) null);
207 }
208
209
210
211
212
213
214
215
216 public static ServiceException badRequest(String reason, Throwable cause) {
217 return badRequest(reason, null, cause);
218 }
219
220
221
222
223
224
225
226
227 public static ServiceException badRequest(String reason, String errorCode) {
228 return badRequest(reason, errorCode, null);
229 }
230
231
232
233
234
235
236
237
238
239 public static ServiceException badRequest(
240 String reason,
241 String errorCode,
242 Throwable cause) {
243 return ServiceException.builder()
244 .httpStatus(400)
245 .reason(reason)
246 .errorCode(errorCode)
247 .cause(cause)
248 .build();
249 }
250
251
252
253
254
255
256 public static ServiceException notFound() {
257 return new ServiceException(404, null);
258 }
259
260
261
262
263
264
265
266 public static ServiceException notFound(Object entityName) {
267 return notFound("Entity", entityName);
268 }
269
270
271
272
273
274
275
276
277 public static ServiceException notFound(String entityType, Object entityName) {
278 return notFoundWithErrorCode(entityType, entityName, null);
279 }
280
281
282
283
284
285
286
287
288 public static ServiceException notFoundWithErrorCode(
289 Object entityName,
290 String errorCode) {
291 return notFoundWithErrorCode("Entity", entityName, errorCode);
292 }
293
294
295
296
297
298
299
300
301
302 public static ServiceException notFoundWithErrorCode(
303 String entityType,
304 Object entityName,
305 String errorCode) {
306 return new ServiceException(404, errorCode,
307 entityType + " with identifier [" + entityName + "] was not found.");
308 }
309
310
311
312
313
314
315 public static ServiceException alreadyExists() {
316 return new ServiceException(409, null);
317 }
318
319
320
321
322
323
324
325 public static ServiceException alreadyExists(
326 Object entityName) {
327 return alreadyExistsWithErrorCode("Entity", entityName, null);
328 }
329
330
331
332
333
334
335
336
337 public static ServiceException alreadyExists(
338 String entityType,
339 Object entityName) {
340 return alreadyExistsWithErrorCode(entityType, entityName, null);
341 }
342
343
344
345
346
347
348
349
350 public static ServiceException alreadyExistsWithErrorCode(
351 Object entityName,
352 String errorCode) {
353 return alreadyExistsWithErrorCode("Entity", entityName, errorCode);
354 }
355
356
357
358
359
360
361
362
363
364 public static ServiceException alreadyExistsWithErrorCode(
365 String entityType,
366 Object entityName,
367 String errorCode) {
368 return new ServiceException(
369 409,
370 isNull(errorCode) || errorCode.isBlank() ? ERROR_CODE_ALREADY_EXISTS : errorCode,
371 entityType + " with identifier [" + entityName + "] already exists.");
372 }
373
374
375
376
377
378
379 public static ServiceException forbidden() {
380 return new ServiceException(403, null);
381 }
382
383
384
385
386
387
388
389 public static ServiceException forbidden(Object entityName) {
390 return forbiddenWithErrorCode(entityName, null);
391 }
392
393
394
395
396
397
398
399
400 public static ServiceException forbidden(String entityType, Object entityName) {
401 return forbiddenWithErrorCode(entityType, entityName, null);
402 }
403
404
405
406
407
408
409
410 public static ServiceException forbiddenWithErrorCode(String errorCode) {
411 return new ServiceException(403, errorCode);
412 }
413
414
415
416
417
418
419
420
421 public static ServiceException forbiddenWithErrorCode(Object entityName, String errorCode) {
422 return new ServiceException(403, errorCode,
423 "Access to entity with identifier [" + entityName + "] is forbidden.");
424 }
425
426
427
428
429
430
431
432
433
434 public static ServiceException forbiddenWithErrorCode(
435 String entityType,
436 Object entityName,
437 String errorCode) {
438 return new ServiceException(403, errorCode,
439 "Access to [" + entityType + "] with identifier [" + entityName + "] is forbidden.");
440 }
441
442
443
444
445
446
447 public static ServiceExceptionBuilder<? extends ServiceException> builder() {
448
449 return new AbstractServiceExceptionBuilder<>() {
450
451 @Serial
452 private static final long serialVersionUID = 2L;
453
454 @Override
455 protected ServiceException buildWith(
456 int httpStatus,
457 String errorCode,
458 String reason,
459 Throwable cause) {
460 return new ServiceException(httpStatus, errorCode, reason, cause);
461 }
462 };
463 }
464
465 }