Add RFC 8040 compliant error handler
[ccsdk/apps.git] / services / src / main / java / org / onap / ccsdk / apps / services / RestExceptionHandler.java
1 package org.onap.ccsdk.apps.services;
2
3 import org.jvnet.hk2.annotations.Service;
4 import org.springframework.beans.ConversionNotSupportedException;
5 import org.springframework.beans.TypeMismatchException;
6 import org.springframework.core.Ordered;
7 import org.springframework.core.annotation.Order;
8 import org.springframework.http.HttpHeaders;
9 import org.springframework.http.HttpStatus;
10 import org.springframework.http.ResponseEntity;
11 import org.springframework.http.converter.HttpMessageNotReadableException;
12 import org.springframework.http.converter.HttpMessageNotWritableException;
13 import org.springframework.validation.BindException;
14 import org.springframework.web.HttpMediaTypeNotAcceptableException;
15 import org.springframework.web.HttpMediaTypeNotSupportedException;
16 import org.springframework.web.HttpRequestMethodNotSupportedException;
17 import org.springframework.web.bind.MethodArgumentNotValidException;
18 import org.springframework.web.bind.MissingPathVariableException;
19 import org.springframework.web.bind.MissingServletRequestParameterException;
20 import org.springframework.web.bind.ServletRequestBindingException;
21 import org.springframework.web.bind.annotation.ControllerAdvice;
22 import org.springframework.web.bind.annotation.ExceptionHandler;
23 import org.springframework.web.bind.annotation.RestController;
24 import org.springframework.web.bind.annotation.RestControllerAdvice;
25 import org.springframework.web.context.request.WebRequest;
26 import org.springframework.web.context.request.async.AsyncRequestTimeoutException;
27 import org.springframework.web.multipart.support.MissingServletRequestPartException;
28 import org.springframework.web.servlet.NoHandlerFoundException;
29 import org.springframework.web.servlet.config.annotation.EnableWebMvc;
30 import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
31
32 import javax.servlet.http.HttpServletRequest;
33
34 @Order(Ordered.HIGHEST_PRECEDENCE)
35 @RestControllerAdvice
36 public class RestExceptionHandler extends ResponseEntityExceptionHandler {
37
38     @Override
39     protected ResponseEntity<Object> handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
40       return createResponseEntity(new RestProtocolError("bad-method", "Method not supported", ex), status);
41     }
42
43     @Override
44     protected ResponseEntity<Object> handleHttpMediaTypeNotSupported(HttpMediaTypeNotSupportedException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
45         return createResponseEntity(new RestProtocolError("bad-media-type", "Media type not supported", ex), status);
46     }
47
48     @Override
49     protected ResponseEntity<Object> handleHttpMediaTypeNotAcceptable(HttpMediaTypeNotAcceptableException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
50         return createResponseEntity(new RestProtocolError("bad-media-type", "Media type not acceptable", ex), status);
51     }
52
53     @Override
54     protected ResponseEntity<Object> handleMissingPathVariable(MissingPathVariableException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
55         return createResponseEntity(new RestApplicationError("missing-path", "Missing path variable", ex), status);
56     }
57
58     @Override
59     protected ResponseEntity<Object> handleMissingServletRequestParameter(MissingServletRequestParameterException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
60         return createResponseEntity(new RestProtocolError("missing-param", "Missing servlet request parameter", ex), status);
61     }
62
63     @Override
64     protected ResponseEntity<Object> handleServletRequestBindingException(ServletRequestBindingException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
65         return createResponseEntity(new RestApplicationError("request-binding", "Servlet binding exception", ex), status);
66     }
67
68     @Override
69     protected ResponseEntity<Object> handleConversionNotSupported(ConversionNotSupportedException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
70         return createResponseEntity(new RestApplicationError("conversion", "Conversion not supported", ex), status);
71     }
72
73     @Override
74     protected ResponseEntity<Object> handleTypeMismatch(TypeMismatchException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
75         return createResponseEntity(new RestProtocolError("type-mismatch", "Type mismatch", ex), status);
76     }
77
78     @Override
79     protected ResponseEntity<Object> handleHttpMessageNotReadable(HttpMessageNotReadableException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
80         return createResponseEntity(new RestProtocolError("bad-message", "HTTP message not readable", ex), status);
81     }
82
83     @Override
84     protected ResponseEntity<Object> handleHttpMessageNotWritable(HttpMessageNotWritableException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
85         return createResponseEntity(new RestProtocolError("bad-message", "HTTP message not writable", ex), status);
86     }
87
88     @Override
89     protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
90         return createResponseEntity(new RestProtocolError("bad-message", "Method argument not valid", ex), status);
91     }
92
93     @Override
94     protected ResponseEntity<Object> handleMissingServletRequestPart(MissingServletRequestPartException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
95         return createResponseEntity(new RestProtocolError("bad-message", "Missing servlet request part", ex), status);
96     }
97
98     @Override
99     protected ResponseEntity<Object> handleBindException(BindException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
100         return createResponseEntity(new RestApplicationError("binding-error", "Missing servlet request part", ex), status);
101     }
102
103     @Override
104     protected ResponseEntity<Object> handleNoHandlerFoundException(NoHandlerFoundException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
105         return createResponseEntity(new RestApplicationError("binding-error", "No handler found", ex), status);
106     }
107
108     @Override
109     protected ResponseEntity<Object> handleAsyncRequestTimeoutException(AsyncRequestTimeoutException ex, HttpHeaders headers, HttpStatus status, WebRequest webRequest) {
110         return createResponseEntity(new RestApplicationError("timeout", "Async request timeout", ex), status);
111     }
112
113     @Override
114     protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body, HttpHeaders headers, HttpStatus status, WebRequest request) {
115         return createResponseEntity(new RestApplicationError("internal-error", "Internal error", ex), status);
116     }
117
118     @ExceptionHandler({RestException.class})
119     protected ResponseEntity<Object> handleRestException(RestException ex, HttpServletRequest request) {
120         RestError error = ex.getRestError();
121         if (request != null) {
122             error.setErrorPath(request.getServletPath());
123         }
124         return createResponseEntity(error,HttpStatus.valueOf(ex.getStatus()));
125     }
126
127     private ResponseEntity<Object> createResponseEntity(RestError restError, HttpStatus status) {
128
129         return new ResponseEntity<>(new RestErrors(restError), status);
130     }
131 }