All Downloads are FREE. Search and download functionalities are using the official Maven repository.

me.alidg.errors.adapter.attributes.ServletErrorAttributes Maven / Gradle / Ivy

package me.alidg.errors.adapter.attributes;

import me.alidg.errors.HttpError;
import me.alidg.errors.WebErrorHandlers;
import me.alidg.errors.adapter.HttpErrorAttributesAdapter;
import org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
import org.springframework.web.context.request.WebRequest;

import java.util.Map;

import static java.util.Objects.requireNonNull;
import static org.springframework.web.context.request.RequestAttributes.SCOPE_REQUEST;

/**
 * Custom implementation of {@link org.springframework.boot.web.servlet.error.ErrorAttributes}
 * which adapts the handled {@link HttpError} to a Spring Boot's compatible error attributes
 * representation.
 *
 * @author Ali Dehghani
 * @see HttpError
 * @see HttpErrorAttributesAdapter
 * @see org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController
 */
public class ServletErrorAttributes extends DefaultErrorAttributes {

    /**
     * To convey the status code from the handled exception to the
     * {@link org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController}.
     */
    private static final String STATUS_CODE_ATTR = "javax.servlet.error.status_code";

    /**
     * To handle exceptions.
     */
    private final WebErrorHandlers webErrorHandlers;

    /**
     * To adapt our representation of an error to Spring Boot's representation.
     */
    private final HttpErrorAttributesAdapter httpErrorAttributesAdapter;

    /**
     * Initializes the error attributes with required dependencies.
     *
     * @param webErrorHandlers           To handle exceptions.
     * @param httpErrorAttributesAdapter To adapt our representation of an error to Spring Boot's representation.
     * @throws NullPointerException When one of the required parameters is null.
     */
    public ServletErrorAttributes(WebErrorHandlers webErrorHandlers,
                                  HttpErrorAttributesAdapter httpErrorAttributesAdapter) {
        requireNonNull(webErrorHandlers, "Web error handlers is required");
        requireNonNull(httpErrorAttributesAdapter, "Adapter is required");

        this.webErrorHandlers = webErrorHandlers;
        this.httpErrorAttributesAdapter = httpErrorAttributesAdapter;
    }

    /**
     * Extracts the thrown exception from the request attributes. If it was null, then checks the stored
     * status code and tries its best to find an exception related to that status code. Finally, handles
     * the exception using the {@link #webErrorHandlers} and adapts the returned {@link HttpError} to a
     * Spring Boot compatible representation.
     *
     * @param webRequest        The current HTTP request.
     * @param includeStackTrace Whether or not to include the stack trace in the error attributes.
     * @return Error details.
     */
    @Override
    public Map getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) {
        Map attributes = super.getErrorAttributes(webRequest, includeStackTrace);
        Throwable exception = getError(webRequest);
        if (exception == null) exception = Exceptions.refineUnknownException(attributes);

        HttpError httpError = webErrorHandlers.handle(exception, webRequest, webRequest.getLocale());
        saveStatusCodeInRequest(webRequest, httpError);

        return httpErrorAttributesAdapter.adapt(httpError);
    }

    /**
     * Storing the handled status code in the request as an attribute. The
     * {@link org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController}
     * would use this status code when it's writing the HTTP response.
     *
     * @param webRequest The request.
     * @param httpError  Represents the handled exception.
     */
    private void saveStatusCodeInRequest(WebRequest webRequest, HttpError httpError) {
        int statusCode = httpError.getHttpStatus().value();
        webRequest.setAttribute(STATUS_CODE_ATTR, statusCode, SCOPE_REQUEST);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy