forked from DSpace/DSpace
/
DSpaceApiExceptionControllerAdvice.java
114 lines (97 loc) · 5.57 KB
/
DSpaceApiExceptionControllerAdvice.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest.exception;
import static org.springframework.web.servlet.DispatcherServlet.EXCEPTION_ATTRIBUTE;
import java.io.IOException;
import java.sql.SQLException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.dspace.app.rest.security.RestAuthenticationService;
import org.dspace.authorize.AuthorizeException;
import org.springframework.beans.TypeMismatchException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.repository.support.QueryMethodParameterConversionException;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
/**
* This Controller advice will handle all exceptions thrown by the DSpace API module
*
* @author Tom Desair (tom dot desair at atmire dot com)
* @author Frederic Van Reet (frederic dot vanreet at atmire dot com)
* @author Andrea Bollini (andrea.bollini at 4science.it)
*/
@ControllerAdvice
public class DSpaceApiExceptionControllerAdvice extends ResponseEntityExceptionHandler {
@Autowired
private RestAuthenticationService restAuthenticationService;
@ExceptionHandler({AuthorizeException.class, RESTAuthorizationException.class})
protected void handleAuthorizeException(HttpServletRequest request, HttpServletResponse response, Exception ex)
throws IOException {
if (restAuthenticationService.hasAuthenticationData(request)) {
sendErrorResponse(request, response, ex, ex.getMessage(), HttpServletResponse.SC_FORBIDDEN);
} else {
sendErrorResponse(request, response, ex, ex.getMessage(), HttpServletResponse.SC_UNAUTHORIZED);
}
}
@ExceptionHandler(IllegalArgumentException.class)
protected void handleIllegalArgumentException(HttpServletRequest request, HttpServletResponse response,
Exception ex) throws IOException {
sendErrorResponse(request, response, ex, ex.getMessage(), HttpServletResponse.SC_BAD_REQUEST);
}
@ExceptionHandler(SQLException.class)
protected void handleSQLException(HttpServletRequest request, HttpServletResponse response, Exception ex)
throws IOException {
sendErrorResponse(request, response, ex,
"An internal database error occurred", HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
@ExceptionHandler(IOException.class)
protected void handleIOException(HttpServletRequest request, HttpServletResponse response, Exception ex)
throws IOException {
sendErrorResponse(request, response, ex,
"An internal read or write operation failed (IO Exception)",
HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
@ExceptionHandler({MissingParameterException.class, QueryMethodParameterConversionException.class})
protected void ParameterConversionException(HttpServletRequest request, HttpServletResponse response, Exception ex)
throws IOException {
//422 is not defined in HttpServletResponse. Its meaning is "Unprocessable Entity".
//Using the value from HttpStatus.
//Since this is a handled exception case, the stack trace will not be returned.
sendErrorResponse(request, response, null,
ex.getMessage(),
HttpStatus.UNPROCESSABLE_ENTITY.value());
}
@Override
protected ResponseEntity<Object> handleMissingServletRequestParameter(MissingServletRequestParameterException ex,
HttpHeaders headers, HttpStatus status, WebRequest request) {
// we want the 422 status for missing parameter as it seems to be the common behavior for REST application, see
// https://stackoverflow.com/questions/3050518/what-http-status-response-code-should-i-use-if-the-request-is-missing-a-required
return super.handleMissingServletRequestParameter(ex, headers, HttpStatus.UNPROCESSABLE_ENTITY, request);
}
@Override
protected ResponseEntity<Object> handleTypeMismatch(TypeMismatchException ex, HttpHeaders headers,
HttpStatus status, WebRequest request) {
// we want the 422 status for type mismatch on parameters as it seems to be the common behavior for REST
// application, see
// https://stackoverflow.com/questions/3050518/what-http-status-response-code-should-i-use-if-the-request-is-missing-a-required
return super.handleTypeMismatch(ex, headers, HttpStatus.UNPROCESSABLE_ENTITY, request);
}
private void sendErrorResponse(final HttpServletRequest request, final HttpServletResponse response,
final Exception ex, final String message, final int statusCode) throws IOException {
//Make sure Spring picks up this exception
request.setAttribute(EXCEPTION_ATTRIBUTE, ex);
//Exception properties will be set by org.springframework.boot.web.support.ErrorPageFilter
response.sendError(statusCode, message);
}
}