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

com.visionarts.powerjambda.exceptions.DefaultActionExceptionResolver Maven / Gradle / Ivy

/*
 * Copyright 2017 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.visionarts.powerjambda.exceptions;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Optional;

import com.amazonaws.services.lambda.runtime.Context;
import com.visionarts.powerjambda.ResponseWriter;
import com.visionarts.powerjambda.annotations.ExceptionHandler;
import com.visionarts.powerjambda.models.ResponseEntity;
import com.visionarts.powerjambda.utils.OptionalUtils;
import com.visionarts.powerjambda.utils.ReflectionUtils;
import com.visionarts.powerjambda.utils.Utils;

/**
 * A ExceptionResolver that resolves the exception
 * through {@code @ExceptionHandler} methods in the action.
 *
 */
public class DefaultActionExceptionResolver implements ExceptionResolver {

    private ResponseWriter, ResponseT> responseWriter;
    private Class exceptionClazz;
    private Class actionClazz;

    /**
     * Create new instance that resolves an exception.
*
* */ public DefaultActionExceptionResolver(ResponseWriter, ResponseT> responseWriter) { this.responseWriter = responseWriter; } /** * Handles an exception and returns the response using the ExceptionHandler method in the action.
*
* * @param action The action with exception handler * @param exception The raised exception * @return The exception as error response to API Gateway * @throws InternalErrorException The exception that occurred */ @Override public ResponseT handleException(Throwable exception, T action, Context context) throws InternalErrorException { this.exceptionClazz = exception.getClass(); this.actionClazz = action.getClass(); try { return responseWriter.writeResponse(handle(exception, action, context)); } catch (IOException e) { throw new InternalErrorException("Failed to write the error response", e); } } /** * Find an {@code @ExceptionHandler} method and invoke it to handle the raised exception.
*
*/ private ResponseEntity handle(Throwable targetException, T action, Context context) throws InternalErrorException { Method method = findExceptionHandler(targetException); Object retVal = invokeMethod(method, action, targetException, context); Utils.requireNonNull(retVal, () -> new InternalErrorException("Exception handler returns null")); return (ResponseEntity) retVal; } private Method findExceptionHandler(Throwable exception) throws InternalErrorException { Optional handler = findExceptionHandler(actionClazz, exceptionClazz); // fallback exception handlers if exists handler = OptionalUtils.or(handler, () -> findExceptionHandler(actionClazz, Exception.class)); handler = OptionalUtils.or(handler, () -> findExceptionHandler(actionClazz, Throwable.class)); return handler.orElseThrow( () -> new InternalErrorException( "Not found any ExceptionHandler for " + exceptionClazz.getName(), exception)); } private Optional findExceptionHandler(Class actionClazz, Class exceptionClazz) { return ReflectionUtils.findAllMethodsWithAnnotation(actionClazz, ExceptionHandler.class) .stream() .filter(m -> Arrays.asList(m.getAnnotation(ExceptionHandler.class).value()).contains(exceptionClazz)) .filter(m -> m.getReturnType().equals(ResponseEntity.class)) .findFirst(); } private Object invokeMethod(Method handler, T action, Throwable targetException, Context context) throws InternalErrorException { Object[] args = new Object[] { targetException, context }; try { return handler.invoke(action, args); } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { throw new InternalErrorException("Method invocation error : " + handler.getName(), e); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy