package interceptors;

import models.ExceptionMessage;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.lang3.StringUtils;
import org.sagebionetworks.bridge.config.BridgeConfig;
import org.sagebionetworks.bridge.exceptions.BridgeServiceException;
import org.sagebionetworks.bridge.exceptions.ConsentRequiredException;
import org.sagebionetworks.bridge.exceptions.NoStackTraceException;
import org.sagebionetworks.bridge.models.UserSessionInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import play.libs.Json;
import play.mvc.Result;
import play.mvc.Results;

@Component("exceptionInterceptor")
public class ExceptionInterceptor implements MethodInterceptor {

    private static final Logger logger = LoggerFactory.getLogger(ExceptionInterceptor.class);

    private BridgeConfig config;

    @Autowired
    public void setBridgeConfig(BridgeConfig config) {
        this.config = config;
    }

    @Override
    public Object invoke(MethodInvocation method) throws Throwable {
        try {
            return method.proceed();
        } catch(Throwable throwable) {
            logException(throwable);
            return getResult(throwable);
        }
    }

    private void logException(final Throwable throwable) {
        final boolean noStackTrace = throwable.getClass().isAnnotationPresent(NoStackTraceException.class);
        if (noStackTrace && config.isLocal()) {
            logger.debug(throwable.getMessage(), throwable);
            return;
        }
        if (noStackTrace) {
            logger.debug(throwable.getMessage());
            return;
        }
        logger.error(throwable.getMessage(), throwable);
    }

    private Result getResult(final Throwable throwable) {
        final int status = getStatusCode(throwable);
        // Consent exceptions return a session payload (you are signed in),
        // but a 412 error status code.
        if (throwable instanceof ConsentRequiredException) {
            ConsentRequiredException cre = (ConsentRequiredException)throwable;
            UserSessionInfo session = new UserSessionInfo(cre.getUserSession());
            return Results.status(cre.getStatusCode(), Json.toJson(session));
        }
        String message = getMessage(throwable, status);
        final ExceptionMessage exceptionMessage = new ExceptionMessage(throwable, message);
        return Results.status(status, Json.toJson(exceptionMessage));
    }

    private int getStatusCode(final Throwable throwable) {
        int status = 500;
        if (throwable instanceof BridgeServiceException) {
            status = ((BridgeServiceException)throwable).getStatusCode();
        }
        return status;
    }

    private String getMessage(final Throwable throwable, final int status) {
        String message = throwable.getMessage();
        if (StringUtils.isBlank(message)) {
            message = HttpStatus.getStatusText(status);
        }
        return message;
    }
}

@@ -47,16 +47,44 @@
 Message;
+%0Aimport models.RequestUtils;
 %0A%0Aimport
@@ -784,24 +784,46 @@
 .libs.Json;%0A
+import play.mvc.Http;%0A
 import play.
@@ -858,16 +858,46 @@
 Results;
+%0Aimport play.mvc.Http.Request;
 %0A%0A@Compo
@@ -1546,32 +1546,250 @@
 le throwable) %7B%0A
+        final Request request = Http.Context.current().request();%0A        final String requestId = RequestUtils.getRequestId(request);%0A        final String msg = %22request: %22 + requestId + %22 %22 + throwable.getMessage();%0A
         final bo
@@ -1953,38 +1953,19 @@
 r.debug(
-throwable.getMessage()
+msg
 , throwa
@@ -2053,38 +2053,19 @@
 r.debug(
-throwable.getMessage()
+msg
 );%0A     
@@ -2110,38 +2110,19 @@
 r.error(
-throwable.getMessage()
+msg
 , throwa

Add request id to logs