/** * Logs the exception at the appropriate level. * * @param exception the {@link Exception} that has to be logged. */ private void log(Exception exception) { String uri = "unknown"; RestMethod restMethod = RestMethod.UNKNOWN; if (request != null) { uri = request.getUri(); restMethod = request.getRestMethod(); } if (exception instanceof RestServiceException) { RestServiceErrorCode errorCode = ((RestServiceException) exception).getErrorCode(); ResponseStatus responseStatus = ResponseStatus.getResponseStatus(errorCode); if (responseStatus == ResponseStatus.InternalServerError) { logger.error( "Internal error handling request {} with method {}.", uri, restMethod, exception); } else { logger.trace("Error handling request {} with method {}.", uri, restMethod, exception); } } else { logger.error( "Unexpected error handling request {} with method {}.", uri, restMethod, exception); } }
/** * Provided a cause, returns an error response with the right status and error message. * * @param cause the cause of the error. * @return a {@link FullHttpResponse} with the error message that can be sent to the client. */ private FullHttpResponse getErrorResponse(Throwable cause) { HttpResponseStatus status; StringBuilder errReason = new StringBuilder(); if (cause instanceof RestServiceException) { RestServiceErrorCode restServiceErrorCode = ((RestServiceException) cause).getErrorCode(); status = getHttpResponseStatus(ResponseStatus.getResponseStatus(restServiceErrorCode)); if (status == HttpResponseStatus.BAD_REQUEST) { errReason.append(" [").append(Utils.getRootCause(cause).getMessage()).append("]"); } } else { nettyMetrics.internalServerErrorCount.inc(); status = HttpResponseStatus.INTERNAL_SERVER_ERROR; } String fullMsg = "Failure: " + status + errReason; logger.trace("Constructed error response for the client - [{}]", fullMsg); FullHttpResponse response; if (request != null && !request.getRestMethod().equals(RestMethod.HEAD)) { response = new DefaultFullHttpResponse( HttpVersion.HTTP_1_1, status, Unpooled.wrappedBuffer(fullMsg.getBytes())); } else { // for HEAD, we cannot send the actual body but we need to return what the length would have // been if this was GET. // https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html (Section 9.4) response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, status); } HttpHeaders.setDate(response, new GregorianCalendar().getTime()); HttpHeaders.setContentLength(response, fullMsg.length()); HttpHeaders.setHeader(response, HttpHeaders.Names.CONTENT_TYPE, "text/plain; charset=UTF-8"); boolean keepAlive = request != null && !request.getRestMethod().equals(RestMethod.POST) && !CLOSE_CONNECTION_ERROR_STATUSES.contains(status); HttpHeaders.setKeepAlive(response, keepAlive); return response; }