class CommonHandler {

    CommonResponse newHttpResponseFromException(CommonRequest request,
            Authentication authentication, Exception exception) throws Exception {
        Exception e = exception;
        if (e instanceof InvocationTargetException) {
            Throwable cause = e.getCause();
            if (cause instanceof Exception) {
                e = (Exception) cause;
            }
        }
        if (e instanceof JsonServiceException) {
            // this is an "expected" exception, no need to log
            JsonServiceException jsonServiceException = (JsonServiceException) e;
            if (jsonServiceException.getStatus() == FORBIDDEN) {
                return handleNotAuthorized(request, authentication);
            } else {
                return newHttpResponseWithMessage(jsonServiceException.getStatus(),
                        jsonServiceException.getMessage());
            }
        }
        logger.error(e.getMessage(), e);
        if (e instanceof SQLException
                && ((SQLException) e).getErrorCode() == H2_STATEMENT_WAS_CANCELED) {
            return newHttpResponseWithMessage(REQUEST_TIMEOUT,
                    "Query timed out (timeout is configurable under Configuration > Advanced)");
        }
        return newHttpResponseWithStackTrace(e, INTERNAL_SERVER_ERROR, null);
    }

}

class CommonHandlerTest {

    private static final int H2_STATEMENT_WAS_CANCELED;
    private static final CommonHandler HTTP_SERVER_HANDLER;

    @Test
    public void shouldCreateNonTimeoutSqlExceptionResponse() throws Exception {

        // given
        Exception e = new SQLException("Another message", "", H2_STATEMENT_WAS_CANCELED + 1);
        // when
        CommonResponse httpResponse = HTTP_SERVER_HANDLER.newHttpResponseFromException(
                mock(CommonRequest.class), mock(Authentication.class), e);
        // then
        String content = (String) httpResponse.getContent();
        ObjectNode node = (ObjectNode) new ObjectMapper().readTree(content);
        assertThat(node.get("message").asText())
                .isEqualTo("java.sql.SQLException: Another message");
        assertThat(node.get("stackTrace")).isNotNull();
        assertThat(httpResponse.getStatus()).isEqualTo(HttpResponseStatus.INTERNAL_SERVER_ERROR);
    }

}