001package org.xbib.elasticsearch.rest; 002 003import org.elasticsearch.ElasticsearchException; 004import org.elasticsearch.common.xcontent.XContentBuilder; 005import org.elasticsearch.rest.RestRequest; 006import org.elasticsearch.rest.RestStatus; 007 008import java.io.IOException; 009 010import static org.elasticsearch.ExceptionsHelper.detailedMessage; 011import static org.xbib.elasticsearch.rest.RestXContentBuilder.restContentBuilder; 012 013public class XContentThrowableRestResponse extends XContentRestResponse { 014 015 public XContentThrowableRestResponse(RestRequest request, Throwable t) throws IOException { 016 this(request, ((t instanceof ElasticsearchException) ? ((ElasticsearchException) t).status() : RestStatus.INTERNAL_SERVER_ERROR), t); 017 } 018 019 public XContentThrowableRestResponse(RestRequest request, RestStatus status, Throwable t) throws IOException { 020 super(request, status, convert(request, status, t)); 021 } 022 023 private static XContentBuilder convert(RestRequest request, RestStatus status, Throwable t) throws IOException { 024 XContentBuilder builder = restContentBuilder(request).startObject() 025 .field("error", detailedMessage(t)) 026 .field("status", status.getStatus()); 027 if (t != null && request.paramAsBoolean("error_trace", false)) { 028 builder.startObject("error_trace"); 029 boolean first = true; 030 while (t != null) { 031 if (!first) { 032 builder.startObject("cause"); 033 } 034 buildThrowable(t, builder); 035 if (!first) { 036 builder.endObject(); 037 } 038 t = t.getCause(); 039 first = false; 040 } 041 builder.endObject(); 042 } 043 builder.endObject(); 044 return builder; 045 } 046 047 private static void buildThrowable(Throwable t, XContentBuilder builder) throws IOException { 048 builder.field("message", t.getMessage()); 049 for (StackTraceElement stElement : t.getStackTrace()) { 050 builder.startObject("at") 051 .field("class", stElement.getClassName()) 052 .field("method", stElement.getMethodName()); 053 if (stElement.getFileName() != null) { 054 builder.field("file", stElement.getFileName()); 055 } 056 if (stElement.getLineNumber() >= 0) { 057 builder.field("line", stElement.getLineNumber()); 058 } 059 builder.endObject(); 060 } 061 } 062}