下面列出了org.springframework.web.context.request.async.AsyncRequestTimeoutException#org.springframework.beans.ConversionNotSupportedException 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Test
public void verify_GENERIC_SERVICE_ERROR_returned_if_ResponseStatusException_with_ConversionNotSupportedException_cause_is_thrown() {
ExtractableResponse response =
given()
.baseUri("http://localhost")
.port(SERVER_PORT)
.log().all()
.when()
.get(CONVERSION_NOT_SUPPORTED_EXCEPTION_ENDPOINT_PATH)
.then()
.log().all()
.extract();
verifyErrorReceived(response, SampleCoreApiError.GENERIC_SERVICE_ERROR);
ResponseStatusException ex = verifyExceptionSeenByBackstopper(ResponseStatusException.class);
ConversionNotSupportedException cnse = verifyExceptionHasCauseOfType(ex, ConversionNotSupportedException.class);
verifyHandlingResult(
SampleCoreApiError.GENERIC_SERVICE_ERROR,
Pair.of("exception_message", quotesToApostrophes(ex.getMessage())),
Pair.of("bad_property_name", cnse.getPropertyName()),
Pair.of("bad_property_value", cnse.getValue().toString()),
Pair.of("required_type", cnse.getRequiredType().toString())
);
}
/**
* Gets properly typed method argument.
* @param parameterType
* @param value
* @return
*/
private <T> T getMethodArgument(Class<T> parameterType, Object value) {
if (parameterType.isInstance(value)) {
return parameterType.cast(value);
}
try {
return new SimpleTypeConverter().convertIfNecessary(value, parameterType);
} catch (ConversionNotSupportedException e) {
if (String.class.equals(parameterType)) {
return (T) String.valueOf(value);
}
throw new ApplicationRuntimeException("Unable to convert method argument type", e);
}
}
/**
* Gets properly typed method argument.
* @param parameterType
* @param value
* @return
*/
private <T> T getMethodArgument(Class<T> parameterType, Object value) {
if (parameterType.isInstance(value)) {
return parameterType.cast(value);
}
try {
return new SimpleTypeConverter().convertIfNecessary(value, parameterType);
} catch (ConversionNotSupportedException e) {
if (String.class.equals(parameterType)) {
return (T) String.valueOf(value);
}
throw new ApplicationRuntimeException("Unable to convert method argument type", e);
}
}
@Test
public void handleConversionNotSupportedException() throws Exception {
ConversionNotSupportedException ex =
new ConversionNotSupportedException(new Object(), String.class, new Exception());
ModelAndView mav = exceptionResolver.resolveException(request, response, null, ex);
assertNotNull("No ModelAndView returned", mav);
assertTrue("No Empty ModelAndView returned", mav.isEmpty());
assertEquals("Invalid status code", 500, response.getStatus());
// SPR-9653
assertSame(ex, request.getAttribute("javax.servlet.error.exception"));
}
@Test
public void handleConversionNotSupportedException() throws Exception {
ConversionNotSupportedException ex =
new ConversionNotSupportedException(new Object(), String.class, new Exception());
ModelAndView mav = exceptionResolver.resolveException(request, response, null, ex);
assertNotNull("No ModelAndView returned", mav);
assertTrue("No Empty ModelAndView returned", mav.isEmpty());
assertEquals("Invalid status code", 500, response.getStatus());
// SPR-9653
assertSame(ex, request.getAttribute("javax.servlet.error.exception"));
}
/**
* 500错误拦截
* @param ex 异常信息
* @return 返回前端异常信息
*/
@ExceptionHandler({ConversionNotSupportedException.class, HttpMessageNotWritableException.class})
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public Result request500(RuntimeException ex){
log.error("错误详情:" + ex.getMessage(),ex);
return Result.errorJson(BaseEnum.INTERNAL_SERVER_ERROR.getMsg(),BaseEnum.INTERNAL_SERVER_ERROR.getIndex());
}
@Test
public void handleConversionNotSupportedException() throws Exception {
ConversionNotSupportedException ex =
new ConversionNotSupportedException(new Object(), String.class, new Exception());
ModelAndView mav = exceptionResolver.resolveException(request, response, null, ex);
assertNotNull("No ModelAndView returned", mav);
assertTrue("No Empty ModelAndView returned", mav.isEmpty());
assertEquals("Invalid status code", 500, response.getStatus());
// SPR-9653
assertSame(ex, request.getAttribute("javax.servlet.error.exception"));
}
@GetMapping(path = CONVERSION_NOT_SUPPORTED_EXCEPTION_ENDPOINT_PATH)
@ResponseBody
public String triggerConversionNotSupportedExceptionEndpoint() {
throw new ResponseStatusException(
HttpStatus.INTERNAL_SERVER_ERROR,
"Synthetic ResponseStatusException with ConversionNotSupportedException cause and 500 status code",
new ConversionNotSupportedException(
new PropertyChangeEvent(this, "somePropertyName", "oldValue", "newValue"),
Integer.class,
null
)
);
}
@ExceptionHandler({ NoSuchRequestHandlingMethodException.class,
ConversionNotSupportedException.class })
@ResponseStatus(value = HttpStatus.NOT_FOUND)
public String handleResourceNotFound(ModelMap model) {
model.put("advancedSearchData", new SearchData());
return "resourceNotFound";
}
/**
* {@link ConversionNotSupportedException}をハンドリングします。
* @param e {@link ConversionNotSupportedException}
* @return {@link ErrorMessage}
* HTTPステータス 500 でレスポンスを返却します。
*/
@ExceptionHandler(ConversionNotSupportedException.class)
@ResponseBody
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
@Override
public ErrorMessage handle(ConversionNotSupportedException e) {
if (L.isDebugEnabled()) {
L.debug(R.getString("D-SPRINGMVC-REST-HANDLER#0007"), e);
}
ErrorMessage error = createServerErrorMessage(HttpStatus.INTERNAL_SERVER_ERROR);
error(error, e);
return error;
}
@Test
public void ConversionNotSupportedExceptionをハンドリングできる() {
ConversionNotSupportedException ex = new ConversionNotSupportedException(new Object(), Class.class, new Throwable());
ErrorMessage message = this.exceptionHandlerSupport.handle(ex);
assertThat(message, notNullValue());
assertThat(message.getStatus(), is(500));
assertThat(message.getMessage(), is("予期しない例外が発生しました。"));
}
private Map<Class, RestExceptionHandler> getDefaultHandlers() {
Map<Class, RestExceptionHandler> map = new HashMap<>();
map.put( NoSuchRequestHandlingMethodException.class, new NoSuchRequestHandlingMethodExceptionHandler() );
map.put( HttpRequestMethodNotSupportedException.class, new HttpRequestMethodNotSupportedExceptionHandler() );
map.put( HttpMediaTypeNotSupportedException.class, new HttpMediaTypeNotSupportedExceptionHandler() );
map.put( MethodArgumentNotValidException.class, new MethodArgumentNotValidExceptionHandler() );
if (ClassUtils.isPresent("javax.validation.ConstraintViolationException", getClass().getClassLoader())) {
map.put( ConstraintViolationException.class, new ConstraintViolationExceptionHandler() );
}
addHandlerTo( map, HttpMediaTypeNotAcceptableException.class, NOT_ACCEPTABLE );
addHandlerTo( map, MissingServletRequestParameterException.class, BAD_REQUEST );
addHandlerTo( map, ServletRequestBindingException.class, BAD_REQUEST );
addHandlerTo( map, ConversionNotSupportedException.class, INTERNAL_SERVER_ERROR );
addHandlerTo( map, TypeMismatchException.class, BAD_REQUEST );
addHandlerTo( map, HttpMessageNotReadableException.class, UNPROCESSABLE_ENTITY );
addHandlerTo( map, HttpMessageNotWritableException.class, INTERNAL_SERVER_ERROR );
addHandlerTo( map, MissingServletRequestPartException.class, BAD_REQUEST );
addHandlerTo(map, Exception.class, INTERNAL_SERVER_ERROR);
// this class didn't exist before Spring 4.0
try {
Class clazz = Class.forName("org.springframework.web.servlet.NoHandlerFoundException");
addHandlerTo(map, clazz, NOT_FOUND);
} catch (ClassNotFoundException ex) {
// ignore
}
return map;
}
@Override
@Nullable
protected ModelAndView doResolveException(
HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex) {
try {
if (ex instanceof HttpRequestMethodNotSupportedException) {
return handleHttpRequestMethodNotSupported(
(HttpRequestMethodNotSupportedException) ex, request, response, handler);
}
else if (ex instanceof HttpMediaTypeNotSupportedException) {
return handleHttpMediaTypeNotSupported(
(HttpMediaTypeNotSupportedException) ex, request, response, handler);
}
else if (ex instanceof HttpMediaTypeNotAcceptableException) {
return handleHttpMediaTypeNotAcceptable(
(HttpMediaTypeNotAcceptableException) ex, request, response, handler);
}
else if (ex instanceof MissingPathVariableException) {
return handleMissingPathVariable(
(MissingPathVariableException) ex, request, response, handler);
}
else if (ex instanceof MissingServletRequestParameterException) {
return handleMissingServletRequestParameter(
(MissingServletRequestParameterException) ex, request, response, handler);
}
else if (ex instanceof ServletRequestBindingException) {
return handleServletRequestBindingException(
(ServletRequestBindingException) ex, request, response, handler);
}
else if (ex instanceof ConversionNotSupportedException) {
return handleConversionNotSupported(
(ConversionNotSupportedException) ex, request, response, handler);
}
else if (ex instanceof TypeMismatchException) {
return handleTypeMismatch(
(TypeMismatchException) ex, request, response, handler);
}
else if (ex instanceof HttpMessageNotReadableException) {
return handleHttpMessageNotReadable(
(HttpMessageNotReadableException) ex, request, response, handler);
}
else if (ex instanceof HttpMessageNotWritableException) {
return handleHttpMessageNotWritable(
(HttpMessageNotWritableException) ex, request, response, handler);
}
else if (ex instanceof MethodArgumentNotValidException) {
return handleMethodArgumentNotValidException(
(MethodArgumentNotValidException) ex, request, response, handler);
}
else if (ex instanceof MissingServletRequestPartException) {
return handleMissingServletRequestPartException(
(MissingServletRequestPartException) ex, request, response, handler);
}
else if (ex instanceof BindException) {
return handleBindException((BindException) ex, request, response, handler);
}
else if (ex instanceof NoHandlerFoundException) {
return handleNoHandlerFoundException(
(NoHandlerFoundException) ex, request, response, handler);
}
else if (ex instanceof AsyncRequestTimeoutException) {
return handleAsyncRequestTimeoutException(
(AsyncRequestTimeoutException) ex, request, response, handler);
}
}
catch (Exception handlerEx) {
if (logger.isWarnEnabled()) {
logger.warn("Failure while trying to resolve exception [" + ex.getClass().getName() + "]", handlerEx);
}
}
return null;
}
@Test
public void conversionNotSupported() {
Exception ex = new ConversionNotSupportedException(new Object(), Object.class, null);
testException(ex);
}
@Override
@Nullable
protected ModelAndView doResolveException(
HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex) {
try {
if (ex instanceof HttpRequestMethodNotSupportedException) {
return handleHttpRequestMethodNotSupported(
(HttpRequestMethodNotSupportedException) ex, request, response, handler);
}
else if (ex instanceof HttpMediaTypeNotSupportedException) {
return handleHttpMediaTypeNotSupported(
(HttpMediaTypeNotSupportedException) ex, request, response, handler);
}
else if (ex instanceof HttpMediaTypeNotAcceptableException) {
return handleHttpMediaTypeNotAcceptable(
(HttpMediaTypeNotAcceptableException) ex, request, response, handler);
}
else if (ex instanceof MissingPathVariableException) {
return handleMissingPathVariable(
(MissingPathVariableException) ex, request, response, handler);
}
else if (ex instanceof MissingServletRequestParameterException) {
return handleMissingServletRequestParameter(
(MissingServletRequestParameterException) ex, request, response, handler);
}
else if (ex instanceof ServletRequestBindingException) {
return handleServletRequestBindingException(
(ServletRequestBindingException) ex, request, response, handler);
}
else if (ex instanceof ConversionNotSupportedException) {
return handleConversionNotSupported(
(ConversionNotSupportedException) ex, request, response, handler);
}
else if (ex instanceof TypeMismatchException) {
return handleTypeMismatch(
(TypeMismatchException) ex, request, response, handler);
}
else if (ex instanceof HttpMessageNotReadableException) {
return handleHttpMessageNotReadable(
(HttpMessageNotReadableException) ex, request, response, handler);
}
else if (ex instanceof HttpMessageNotWritableException) {
return handleHttpMessageNotWritable(
(HttpMessageNotWritableException) ex, request, response, handler);
}
else if (ex instanceof MethodArgumentNotValidException) {
return handleMethodArgumentNotValidException(
(MethodArgumentNotValidException) ex, request, response, handler);
}
else if (ex instanceof MissingServletRequestPartException) {
return handleMissingServletRequestPartException(
(MissingServletRequestPartException) ex, request, response, handler);
}
else if (ex instanceof BindException) {
return handleBindException((BindException) ex, request, response, handler);
}
else if (ex instanceof NoHandlerFoundException) {
return handleNoHandlerFoundException(
(NoHandlerFoundException) ex, request, response, handler);
}
else if (ex instanceof AsyncRequestTimeoutException) {
return handleAsyncRequestTimeoutException(
(AsyncRequestTimeoutException) ex, request, response, handler);
}
}
catch (Exception handlerEx) {
if (logger.isWarnEnabled()) {
logger.warn("Failure while trying to resolve exception [" + ex.getClass().getName() + "]", handlerEx);
}
}
return null;
}
@Test
public void conversionNotSupported() {
Exception ex = new ConversionNotSupportedException(new Object(), Object.class, null);
testException(ex);
}
/**
* 500错误
*/
@ExceptionHandler({ConversionNotSupportedException.class, HttpMessageNotWritableException.class})
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public BaseResponse server500(HttpServletResponse resp,Exception e) {
return this.serverErrorHandler();
}
@Override
@SuppressWarnings("deprecation")
protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) {
try {
if (ex instanceof org.springframework.web.servlet.mvc.multiaction.NoSuchRequestHandlingMethodException) {
return handleNoSuchRequestHandlingMethod((org.springframework.web.servlet.mvc.multiaction.NoSuchRequestHandlingMethodException) ex,
request, response, handler);
}
else if (ex instanceof HttpRequestMethodNotSupportedException) {
return handleHttpRequestMethodNotSupported((HttpRequestMethodNotSupportedException) ex, request,
response, handler);
}
else if (ex instanceof HttpMediaTypeNotSupportedException) {
return handleHttpMediaTypeNotSupported((HttpMediaTypeNotSupportedException) ex, request, response,
handler);
}
else if (ex instanceof HttpMediaTypeNotAcceptableException) {
return handleHttpMediaTypeNotAcceptable((HttpMediaTypeNotAcceptableException) ex, request, response,
handler);
}
else if (ex instanceof MissingPathVariableException) {
return handleMissingPathVariable((MissingPathVariableException) ex, request,
response, handler);
}
else if (ex instanceof MissingServletRequestParameterException) {
return handleMissingServletRequestParameter((MissingServletRequestParameterException) ex, request,
response, handler);
}
else if (ex instanceof ServletRequestBindingException) {
return handleServletRequestBindingException((ServletRequestBindingException) ex, request, response,
handler);
}
else if (ex instanceof ConversionNotSupportedException) {
return handleConversionNotSupported((ConversionNotSupportedException) ex, request, response, handler);
}
else if (ex instanceof TypeMismatchException) {
return handleTypeMismatch((TypeMismatchException) ex, request, response, handler);
}
else if (ex instanceof HttpMessageNotReadableException) {
return handleHttpMessageNotReadable((HttpMessageNotReadableException) ex, request, response, handler);
}
else if (ex instanceof HttpMessageNotWritableException) {
return handleHttpMessageNotWritable((HttpMessageNotWritableException) ex, request, response, handler);
}
else if (ex instanceof MethodArgumentNotValidException) {
return handleMethodArgumentNotValidException((MethodArgumentNotValidException) ex, request, response,
handler);
}
else if (ex instanceof MissingServletRequestPartException) {
return handleMissingServletRequestPartException((MissingServletRequestPartException) ex, request,
response, handler);
}
else if (ex instanceof BindException) {
return handleBindException((BindException) ex, request, response, handler);
}
else if (ex instanceof NoHandlerFoundException) {
return handleNoHandlerFoundException((NoHandlerFoundException) ex, request, response, handler);
}
else if (ex instanceof AsyncRequestTimeoutException) {
return handleAsyncRequestTimeoutException(
(AsyncRequestTimeoutException) ex, request, response, handler);
}
}
catch (Exception handlerException) {
if (logger.isWarnEnabled()) {
logger.warn("Handling of [" + ex.getClass().getName() + "] resulted in Exception", handlerException);
}
}
return null;
}
@Override
protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) {
try {
if (ex instanceof NoSuchRequestHandlingMethodException) {
return handleNoSuchRequestHandlingMethod((NoSuchRequestHandlingMethodException) ex, request, response,
handler);
}
else if (ex instanceof HttpRequestMethodNotSupportedException) {
return handleHttpRequestMethodNotSupported((HttpRequestMethodNotSupportedException) ex, request,
response, handler);
}
else if (ex instanceof HttpMediaTypeNotSupportedException) {
return handleHttpMediaTypeNotSupported((HttpMediaTypeNotSupportedException) ex, request, response,
handler);
}
else if (ex instanceof HttpMediaTypeNotAcceptableException) {
return handleHttpMediaTypeNotAcceptable((HttpMediaTypeNotAcceptableException) ex, request, response,
handler);
}
else if (ex instanceof MissingPathVariableException) {
return handleMissingPathVariable((MissingPathVariableException) ex, request,
response, handler);
}
else if (ex instanceof MissingServletRequestParameterException) {
return handleMissingServletRequestParameter((MissingServletRequestParameterException) ex, request,
response, handler);
}
else if (ex instanceof ServletRequestBindingException) {
return handleServletRequestBindingException((ServletRequestBindingException) ex, request, response,
handler);
}
else if (ex instanceof ConversionNotSupportedException) {
return handleConversionNotSupported((ConversionNotSupportedException) ex, request, response, handler);
}
else if (ex instanceof TypeMismatchException) {
return handleTypeMismatch((TypeMismatchException) ex, request, response, handler);
}
else if (ex instanceof HttpMessageNotReadableException) {
return handleHttpMessageNotReadable((HttpMessageNotReadableException) ex, request, response, handler);
}
else if (ex instanceof HttpMessageNotWritableException) {
return handleHttpMessageNotWritable((HttpMessageNotWritableException) ex, request, response, handler);
}
else if (ex instanceof MethodArgumentNotValidException) {
return handleMethodArgumentNotValidException((MethodArgumentNotValidException) ex, request, response,
handler);
}
else if (ex instanceof MissingServletRequestPartException) {
return handleMissingServletRequestPartException((MissingServletRequestPartException) ex, request,
response, handler);
}
else if (ex instanceof BindException) {
return handleBindException((BindException) ex, request, response, handler);
}
else if (ex instanceof NoHandlerFoundException) {
return handleNoHandlerFoundException((NoHandlerFoundException) ex, request, response, handler);
}
}
catch (Exception handlerException) {
if (logger.isWarnEnabled()) {
logger.warn("Handling of [" + ex.getClass().getName() + "] resulted in Exception", handlerException);
}
}
return null;
}
@Test
public void conversionNotSupported() {
Exception ex = new ConversionNotSupportedException(new Object(), Object.class, null);
testException(ex);
}
protected ApiExceptionHandlerListenerResult handleTypeMismatchException(
TypeMismatchException ex,
List<Pair<String, String>> extraDetailsForLogging,
boolean addBaseExceptionMessageToLoggingDetails
) {
// The metadata will only be used if it's a 400 error.
Map<String, Object> metadata = new LinkedHashMap<>();
if (addBaseExceptionMessageToLoggingDetails) {
utils.addBaseExceptionMessageToExtraDetailsForLogging(ex, extraDetailsForLogging);
}
String badPropName = extractPropertyName(ex);
if (badPropName == null) {
badPropName = ex.getPropertyName();
}
String badPropValue = (ex.getValue() == null) ? null : String.valueOf(ex.getValue());
String requiredTypeNoInfoLeak = extractRequiredTypeNoInfoLeak(ex);
extraDetailsForLogging.add(Pair.of("bad_property_name", badPropName));
if (badPropName != null) {
metadata.put("bad_property_name", badPropName);
}
extraDetailsForLogging.add(Pair.of("bad_property_value", String.valueOf(ex.getValue())));
if (badPropValue != null) {
metadata.put("bad_property_value", badPropValue);
}
extraDetailsForLogging.add(Pair.of("required_type", String.valueOf(ex.getRequiredType())));
if (requiredTypeNoInfoLeak != null) {
metadata.put("required_type", requiredTypeNoInfoLeak);
}
// ConversionNotSupportedException is a special case of TypeMismatchException that should be treated as
// a 500 internal service error. See Spring's DefaultHandlerExceptionResolver and/or
// ResponseEntityExceptionHandler for verification.
if (ex instanceof ConversionNotSupportedException) {
// We can add even more context log details if it's a MethodArgumentConversionNotSupportedException.
if (ex instanceof MethodArgumentConversionNotSupportedException) {
MethodArgumentConversionNotSupportedException macnsEx = (MethodArgumentConversionNotSupportedException)ex;
extraDetailsForLogging.add(Pair.of("method_arg_name", macnsEx.getName()));
extraDetailsForLogging.add(Pair.of("method_arg_target_param", macnsEx.getParameter().toString()));
}
return handleError(projectApiErrors.getGenericServiceError(), extraDetailsForLogging);
}
else {
// All other TypeMismatchExceptions should be treated as a 400, and we can/should include the metadata.
// We can add even more context log details if it's a MethodArgumentTypeMismatchException.
if (ex instanceof MethodArgumentTypeMismatchException) {
MethodArgumentTypeMismatchException matmEx = (MethodArgumentTypeMismatchException)ex;
extraDetailsForLogging.add(Pair.of("method_arg_name", matmEx.getName()));
extraDetailsForLogging.add(Pair.of("method_arg_target_param", matmEx.getParameter().toString()));
}
return handleError(
new ApiErrorWithMetadata(projectApiErrors.getTypeConversionApiError(), metadata),
extraDetailsForLogging
);
}
}
@DataProvider(value = {
"true",
"false"
})
@Test
public void shouldHandleException_returns_GENERIC_SERVICE_ERROR_for_ConversionNotSupportedException(
boolean isMethodArgConversionEx
) {
// given
Object valueObj = "notAnInteger";
Class<?> requiredType = Integer.class;
Throwable someCause = new RuntimeException("some cause");
String methodArgName = "fooArg";
MethodParameter methodParam = mock(MethodParameter.class);
ConversionNotSupportedException ex =
(isMethodArgConversionEx)
? new MethodArgumentConversionNotSupportedException(valueObj, requiredType, methodArgName, methodParam, someCause)
: new ConversionNotSupportedException(valueObj, requiredType, someCause);
String expectedBadPropName = (isMethodArgConversionEx) ? methodArgName : null;
List<Pair<String, String>> expectedExtraDetailsForLogging = new ArrayList<>(
Arrays.asList(
Pair.of("exception_message", ex.getMessage()),
Pair.of("bad_property_name", expectedBadPropName),
Pair.of("bad_property_value", String.valueOf(valueObj)),
Pair.of("required_type", String.valueOf(requiredType))
)
);
if (isMethodArgConversionEx) {
expectedExtraDetailsForLogging.add(Pair.of("method_arg_name", methodArgName));
expectedExtraDetailsForLogging.add(Pair.of("method_arg_target_param", methodParam.toString()));
}
// when
ApiExceptionHandlerListenerResult result = listener.shouldHandleException(ex);
// then
validateResponse(result, true, singletonList(testProjectApiErrors.getGenericServiceError()));
assertThat(result.extraDetailsForLogging).containsExactlyInAnyOrderElementsOf(expectedExtraDetailsForLogging);
}
protected @NotNull ApiExceptionHandlerListenerResult handleResponseStatusException(
@NotNull ResponseStatusException ex
) {
// ResponseStatusException is technically in spring-web, so it could be handled in backstopper-spring-web's
// OneOffSpringCommonFrameworkExceptionHandlerListener, except that it's also spring 5 so we'd have to
// have yet another module for backstopper-spring-web5. Or we'd have to do a bunch of obnoxious reflection.
// Since Spring WebFlux seems to be the only place ResponseStatusException is used, we'll just shove this
// logic here for now. It can be moved later if needed.
int statusCode = ex.getStatus().value();
List<Pair<String, String>> extraDetailsForLogging = new ArrayList<>();
utils.addBaseExceptionMessageToExtraDetailsForLogging(ex, extraDetailsForLogging);
addExtraDetailsForLoggingForResponseStatusException(ex, extraDetailsForLogging);
// Search for a more specific way to handle this based on the cause.
Throwable exCause = ex.getCause();
if (exCause instanceof TypeMismatchException) {
// If the cause is a TypeMismatchException and status code is acceptable, then we can have the
// handleTypeMismatchException(...) method deal with it for a more specific response.
// For safety make sure the status code is one we expect.
TypeMismatchException tmeCause = (TypeMismatchException) ex.getCause();
int expectedStatusCode = (tmeCause instanceof ConversionNotSupportedException) ? 500 : 400;
if (statusCode == expectedStatusCode) {
// The specific cause exception type and the status code match,
// so we can use handleTypeMismatchException(...).
return handleTypeMismatchException(tmeCause, extraDetailsForLogging, false);
}
}
else if (exCause instanceof DecodingException && statusCode == 400) {
return handleError(projectApiErrors.getMalformedRequestApiError(), extraDetailsForLogging);
}
// Exception cause didn't help. Try parsing the reason message.
String exReason = (ex.getReason() == null) ? "" : ex.getReason();
String[] exReasonWords = exReason.split(" ");
RequiredParamData missingRequiredParam = parseExReasonForMissingRequiredParam(exReasonWords, exReason);
if (missingRequiredParam != null && statusCode == 400) {
return handleError(
new ApiErrorWithMetadata(
projectApiErrors.getMalformedRequestApiError(),
Pair.of("missing_param_name", missingRequiredParam.paramName),
Pair.of("missing_param_type", missingRequiredParam.paramType)
),
extraDetailsForLogging
);
}
else if (exReason.startsWith("Request body is missing") && statusCode == 400) {
return handleError(projectApiErrors.getMissingExpectedContentApiError(), extraDetailsForLogging);
}
// For any other ResponseStatusException we'll search for an appropriate ApiError by status code.
return handleError(
determineApiErrorToUseForGenericResponseStatusCode(statusCode),
extraDetailsForLogging
);
}
@Test
public void testCopyList(){
Date now = new Date();
Date createTime = new Date(now.getTime()+3600000);
String userName = "testName";
long id = 111333L;
CapitalBean srcBean = new CapitalBean();
srcBean.setId(id);
srcBean.setUserName(userName);
srcBean.setBirthday(now);
srcBean.setCreateTime(createTime);
long dataId = 2342332;
String subName = "subNameTest";
CapitalBean2 srcData = new CapitalBean2();
srcData.setId(dataId);
srcData.setSubName(subName);
srcData.setCreateTime(createTime);
List<CapitalBean2> datas = new ArrayList<CopyUtilsTest.CapitalBean2>();
datas.add(srcData);
srcBean.setDatas(datas);
try {
UnderlineBeanWithoutCloneable underlineBeanWithoutCloneable = CopyUtils.copy(UnderlineBeanWithoutCloneable.class, srcBean);
Assert.fail("it should be faield");
} catch (Exception e) {
Assert.assertTrue(ConversionNotSupportedException.class.isInstance(e));
}
UnderlineBean target = CopyUtils.copy(UnderlineBean.class, srcBean);
Assert.assertEquals(userName, target.getUser_name());
Assert.assertEquals(id, target.getId());
Assert.assertEquals(createTime, target.getCreate_time());
Assert.assertEquals(now, target.getBirthday());
Assert.assertEquals(srcBean.getId(), target.getId());
Assert.assertEquals(srcBean.getUserName(), target.getUser_name());
Assert.assertEquals(srcBean.getBirthday(), target.getBirthday());
Assert.assertEquals(srcBean.getCreateTime(), target.getCreate_time());
Assert.assertNotNull(target.getDatas());
Assert.assertEquals(1, target.getDatas().size());
UnderlineBean2 targetData = target.getDatas().get(0);
Assert.assertEquals(dataId, targetData.getId());
Assert.assertEquals(subName, targetData.getSub_name());
Assert.assertEquals(createTime, targetData.getCreate_time());
srcBean = CopyUtils.copy(new CapitalBean(), target);
Assert.assertEquals(userName, srcBean.getUserName());
Assert.assertEquals(id, srcBean.getId());
Assert.assertEquals(createTime, srcBean.getCreateTime());
Assert.assertEquals(now, srcBean.getBirthday());
Assert.assertEquals(srcBean.getId(), target.getId());
Assert.assertEquals(srcBean.getUserName(), target.getUser_name());
Assert.assertEquals(srcBean.getBirthday(), target.getBirthday());
Assert.assertEquals(srcBean.getCreateTime(), target.getCreate_time());
}
@ExceptionHandler({ NoSuchRequestHandlingMethodException.class,
ConversionNotSupportedException.class })
@ResponseStatus(value = HttpStatus.NOT_FOUND)
public String handleResourceNotFound() {
return "resourceNotFound";
}
@ExceptionHandler({NoSuchRequestHandlingMethodException.class, ConversionNotSupportedException.class})
@ResponseStatus(value = HttpStatus.NOT_FOUND)
public String handleResourceNotFound(){
return "resourceNotFound";
}
/**
* Handle the case when a {@link org.springframework.web.bind.WebDataBinder} conversion cannot occur.
* <p>The default implementation sends an HTTP 500 error, and returns an empty {@code ModelAndView}.
* Alternatively, a fallback view could be chosen, or the ConversionNotSupportedException could be
* rethrown as-is.
* @param ex the ConversionNotSupportedException to be handled
* @param request current HTTP request
* @param response current HTTP response
* @param handler the executed handler
* @return an empty ModelAndView indicating the exception was handled
* @throws IOException potentially thrown from {@link HttpServletResponse#sendError}
*/
protected ModelAndView handleConversionNotSupported(ConversionNotSupportedException ex,
HttpServletRequest request, HttpServletResponse response, @Nullable Object handler) throws IOException {
sendServerError(ex, request, response);
return new ModelAndView();
}
/**
* Handle the case when a {@link org.springframework.web.bind.WebDataBinder} conversion cannot occur.
* <p>The default implementation sends an HTTP 500 error, and returns an empty {@code ModelAndView}.
* Alternatively, a fallback view could be chosen, or the ConversionNotSupportedException could be
* rethrown as-is.
* @param ex the ConversionNotSupportedException to be handled
* @param request current HTTP request
* @param response current HTTP response
* @param handler the executed handler
* @return an empty ModelAndView indicating the exception was handled
* @throws IOException potentially thrown from {@link HttpServletResponse#sendError}
*/
protected ModelAndView handleConversionNotSupported(ConversionNotSupportedException ex,
HttpServletRequest request, HttpServletResponse response, @Nullable Object handler) throws IOException {
sendServerError(ex, request, response);
return new ModelAndView();
}
/**
* Handle the case when a {@link org.springframework.web.bind.WebDataBinder} conversion cannot occur.
* <p>The default implementation sends an HTTP 500 error, and returns an empty {@code ModelAndView}.
* Alternatively, a fallback view could be chosen, or the TypeMismatchException could be rethrown as-is.
* @param ex the ConversionNotSupportedException to be handled
* @param request current HTTP request
* @param response current HTTP response
* @param handler the executed handler
* @return an empty ModelAndView indicating the exception was handled
* @throws IOException potentially thrown from response.sendError()
*/
protected ModelAndView handleConversionNotSupported(ConversionNotSupportedException ex,
HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
if (logger.isWarnEnabled()) {
logger.warn("Failed to convert request element: " + ex);
}
sendServerError(ex, request, response);
return new ModelAndView();
}
/**
* 500相关异常
*
* @param rep {@link HttpServletResponse}
* @param ex {@link Exception}
* @return {@link RestResponse}
*/
@ExceptionHandler({ConversionNotSupportedException.class, HttpMessageNotWritableException.class})
public RestResponse server500(HttpServletRequest req, HttpServletResponse rep, Exception ex) {
log.error("---server500 Handler---Host {}, invokes url {}, ERROR: {}", req.getRemoteHost(), req.getRequestURL(), ex.getMessage(), ex);
rep.setStatus(ErrorCode.INTERNAL_SERVER_ERROR.getCode());
return RestResponse.fail(ErrorCode.INTERNAL_SERVER_ERROR.getCode(), ErrorCode.INTERNAL_SERVER_ERROR.getMsg());
}