ApiExceptionHandlerListenerResult result = shouldHandleApiException(ex); return doHandleApiException(result.errors, result.extraDetailsForLogging, result.extraResponseHeaders, ex, request);
/** * "Unwraps" the given exception by digging through the {@link Throwable#getCause()} chain until a non-wrapper * exception type is found. Uses {@link #getWrapperExceptionClassNames()} as the set of exception classes that are * considered wrappers. * * @param error The exception that may (or may not) need to be "unwrapped". * @return The root/core cause exception that is not a wrapper exception - the passed-in exception will be returned * as-is if it is not a wrapper exception or if it has no cause. */ protected Throwable unwrapAndFindCoreException(Throwable error) { if (error == null || error.getCause() == null || error.getCause() == error) return error; // At this point there must be a non-null cause, and it is not a reference to itself. See if it's a wrapper. if (getWrapperExceptionClassNames().contains(error.getClass().getName())) { // This is a wrapper. Extract the cause. error = error.getCause(); // Recursively unwrap until we get something that is not unwrappable error = unwrapAndFindCoreException(error); } return error; }
RequestInfoForLogging request ) { Throwable coreException = unwrapAndFindCoreException(originalException); if (shouldLogStackTrace( highestPriorityStatusCode, filteredClientErrors, originalException, coreException, request )) { T frameworkRepresentation = prepareFrameworkRepresentation( errorContractDTO, highestPriorityStatusCode, filteredClientErrors, originalException, request ); Map<String, List<String>> evenMoreExtraHeadersForResponse = extraHeadersForResponse( frameworkRepresentation, errorContractDTO, highestPriorityStatusCode, filteredClientErrors, originalException, request
/** * @return An {@link ApiExceptionHandlerListenerResult} indicating whether we should handle the given exception. * If {@link ApiExceptionHandlerListenerResult#shouldHandleResponse} is true then * {@link ApiExceptionHandlerListenerResult#errors} and * {@link ApiExceptionHandlerListenerResult#extraDetailsForLogging} must be filled in appropriately and * ready for passing in to * {@link #doHandleApiException(SortedApiErrorSet, List, List, Throwable, RequestInfoForLogging)}. If it is * false then the given exception will be ignored by this class (and should therefore ultimately be handled * by this project's implementation of {@link UnhandledExceptionHandlerBase}). */ protected ApiExceptionHandlerListenerResult shouldHandleApiException(Throwable ex) { // The original exception might be a "wrapper" exception. If so, unwrap it so we can send the core exception // through our list of listeners. Throwable coreEx = unwrapAndFindCoreException(ex); // Run through each listener looking for one that wants to handle the core exception. for (ApiExceptionHandlerListener listener : apiExceptionHandlerListenerList) { ApiExceptionHandlerListenerResult result = listener.shouldHandleException(coreEx); if (result.shouldHandleResponse) return result; } // We didn't have any handler that wanted to deal with this exception, so return an "ignore it" response. return ApiExceptionHandlerListenerResult.ignoreResponse(); }