/** * @return The basic set of handler listeners that are appropriate for most JAX-RS applications. */ public static List<ApiExceptionHandlerListener> defaultApiExceptionHandlerListeners( ProjectApiErrors projectApiErrors, ApiExceptionHandlerUtils utils ) { return Arrays.asList( new GenericApiExceptionHandlerListener(), new ServersideValidationErrorHandlerListener(projectApiErrors, utils), new ClientDataValidationErrorHandlerListener(projectApiErrors, utils), new DownstreamNetworkExceptionHandlerListener(projectApiErrors), new JaxRsWebApplicationExceptionHandlerListener(projectApiErrors, utils)); }
/** * Helper method for translating the given set of constraint violations set into a set of {@link ApiError} objects * by calling {@link #convertValidationErrorToApiError(ConstraintViolation)} on each one. */ protected SortedApiErrorSet convertValidationErrorsToApiErrors(List<ConstraintViolation<Object>> validationErrors) { SortedApiErrorSet apiErrors = new SortedApiErrorSet(); for (ConstraintViolation<Object> validationError : validationErrors) { apiErrors.add(convertValidationErrorToApiError(validationError)); } return apiErrors; }
@Override public ApiExceptionHandlerListenerResult shouldHandleException(Throwable ex) { // We only care about ClientDataValidationErrors. if (ex instanceof ClientDataValidationError) { List<Pair<String, String>> extraDetailsForLogging = new ArrayList<>(); SortedApiErrorSet apiErrors = processClientDataValidationError( (ClientDataValidationError)ex, extraDetailsForLogging ); return ApiExceptionHandlerListenerResult.handleResponse(apiErrors, extraDetailsForLogging); } // Not a ClientDataValidationError. Ignore. return ApiExceptionHandlerListenerResult.ignoreResponse(); }
@Override public ApiExceptionHandlerListenerResult shouldHandleException(Throwable ex) { SortedApiErrorSet handledErrors = null; List<Pair<String, String>> extraDetailsForLogging = new ArrayList<>(); // Look for exceptions we're supposed to handle. if (isTemporaryProblem(ex, extraDetailsForLogging)) { handledErrors = singletonSortedSetOf(projectApiErrors.getTemporaryServiceProblemApiError()); } else if (ex instanceof ServerHttpStatusCodeException) { handledErrors = processServerHttpStatusCodeException( (ServerHttpStatusCodeException) ex, extraDetailsForLogging ); } else if (ex instanceof ServerUnknownHttpStatusCodeException) { handledErrors = processServerUnknownHttpStatusCodeException( (ServerUnknownHttpStatusCodeException) ex, extraDetailsForLogging ); } if (handledErrors != null) return ApiExceptionHandlerListenerResult.handleResponse(handledErrors, extraDetailsForLogging); // Not an exception we care about - ignore it. return ApiExceptionHandlerListenerResult.ignoreResponse(); }
/** * @return Helper method for processing the given {@link ServerHttpStatusCodeException} by adding relevant log pairs * to extraDetailsForLogging and returning the appropriate {@link SortedApiErrorSet}. */ protected SortedApiErrorSet processServerHttpStatusCodeException(ServerHttpStatusCodeException ex, List<Pair<String, String>> extraDetailsForLogging) { // Add status code. Integer statusCodeReceived = ex.getResponseStatusCode(); extraDetailsForLogging.add(Pair.of("status_code", String.valueOf(statusCodeReceived))); // Add the raw response if desired. if (shouldLogRawResponse(ex)) { extraDetailsForLogging.add(Pair.of("raw_response_string", ex.getRawResponseBody())); } // Special-case 429 errors if desired (if the downstream system is being rate limited then we might want to // propagate that information to the caller). if (INT_429_BOXED.equals(statusCodeReceived) && shouldPropagate429Error(ex)) { return singletonSortedSetOf(projectApiErrors.getTooManyRequestsApiError()); } // If the downstream system responded with a 503 then we should too. if (INT_503_BOXED.equals(statusCodeReceived)) return singletonSortedSetOf(projectApiErrors.getOutsideDependencyReturnedTemporaryErrorApiError()); // Nothing left but to indicate an unrecoverable error from the downstream system. return singletonSortedSetOf(projectApiErrors.getOusideDependencyReturnedAnUnrecoverableErrorApiError()); }
@Override public ApiExceptionHandlerListenerResult shouldHandleException(Throwable ex) { ServersideValidationError sve = null; // Try to get the ServersideValidationError if (ex instanceof ServersideValidationError) sve = (ServersideValidationError)ex; else if ((ex instanceof DownstreamRequestOrResponseBodyFailedValidationException) && (ex.getCause() instanceof ServersideValidationError)) { sve = (ServersideValidationError) ex.getCause(); } if (sve != null) { // Process the ServersideValidationError to add logging details and get the appropriate SortedApiErrorSet. List<Pair<String, String>> extraDetailsForLogging = new ArrayList<>(); SortedApiErrorSet apiErrors = processServersideValidationError(sve, extraDetailsForLogging); return ApiExceptionHandlerListenerResult.handleResponse(apiErrors, extraDetailsForLogging); } // Not an exception we know how to handle - ignore it. return ApiExceptionHandlerListenerResult.ignoreResponse(); }
return convertValidationErrorsToApiErrors(ex.getViolations());
/** * Returns the default list of {@link ApiExceptionHandlerListener}s that should work for most applications without * any further additions. */ public static List<ApiExceptionHandlerListener> defaultHandlerListeners(ProjectApiErrors projectApiErrors, ApiExceptionHandlerUtils utils) { return Arrays.asList(new GenericApiExceptionHandlerListener(), new ServersideValidationErrorHandlerListener(projectApiErrors, utils), new ClientDataValidationErrorHandlerListener(projectApiErrors, utils), new DownstreamNetworkExceptionHandlerListener(projectApiErrors), new BackstopperRiposteFrameworkErrorHandlerListener(projectApiErrors)); }