/*
 * Licensed to CRATE Technology GmbH ("Crate") under one or more contributor
 * license agreements.  See the NOTICE file distributed with this work for
 * additional information regarding copyright ownership.  Crate licenses
 * this file to you 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.
 *
 * However, if you have executed another commercial license agreement
 * with Crate these terms will supersede the license and you may use the
 * software solely pursuant to the terms of the relevant commercial agreement.
 */

package io.crate.rest.action;

import io.crate.action.sql.SQLActionException;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.ExceptionsHelper;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.rest.BytesRestResponse;
import org.elasticsearch.rest.RestChannel;
import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.rest.RestResponse;
import org.elasticsearch.rest.RestStatus;

import java.io.IOException;

import static io.crate.exceptions.Exceptions.userFriendlyMessage;


class CrateThrowableRestResponse extends RestResponse {

    private final RestStatus status;
    private final BytesReference content;
    private final String contentType;

    CrateThrowableRestResponse(RestChannel channel, Throwable t) throws IOException {
        status = (t instanceof ElasticsearchException) ?
            ((ElasticsearchException) t).status() :
            RestStatus.INTERNAL_SERVER_ERROR;
        if (channel.request().method() == RestRequest.Method.HEAD) {
            this.content = BytesArray.EMPTY;
            this.contentType = BytesRestResponse.TEXT_CONTENT_TYPE;
        } else {
            XContentBuilder builder = convert(channel, t);
            this.content = builder.bytes();
            this.contentType = builder.contentType().mediaType();
        }
    }

    private static XContentBuilder convert(RestChannel channel, Throwable t) throws IOException {
        XContentBuilder builder = channel.newBuilder().startObject()
            .startObject("error");

        SQLActionException sqlActionException = null;
        builder.field("message", userFriendlyMessage(t));
        if (t instanceof SQLActionException) {
            sqlActionException = (SQLActionException) t;
            builder.field("code", sqlActionException.errorCode());
        } else {
            builder.field("code", 5000);
        }

        builder.endObject();

        if (t != null && channel.request().paramAsBoolean("error_trace", false)
            && sqlActionException != null) {
            builder.field("error_trace", ExceptionsHelper.stackTrace(t));
        }
        builder.endObject();
        return builder;
    }

    @Override
    public String contentType() {
        return contentType;
    }

    @Override
    public BytesReference content() {
        return content;
    }

    @Override
    public RestStatus status() {
        return status;
    }
}



@@ -2330,18 +2330,109 @@
 ert(
-channel, t
+%0A                channel.newErrorBuilder(), t, channel.request().paramAsBoolean(%22error_trace%22, false)
 );%0A 
@@ -2604,175 +2604,130 @@
 ert(
-RestChannel channel, Throwable t) throws IOException %7B%0A        XContentBuilder builder = channel.newBuilder().startObject()%0A            .startObject(%22error%22);%0A%0A       
+XContentBuilder builder, Throwable t, boolean includeErrorTrace) throws IOException %7B%0A        int errorCode = t instanceof
  SQL
@@ -2742,19 +2742,23 @@
 ception 
-sql
+? ((SQL
 ActionEx
@@ -2768,179 +2768,149 @@
 tion
- = null;%0A        builder.field(%22message%22, userFriendlyMessage(t));%0A        if (t instanceof SQLActionException) %7B%0A            sqlActionException = (SQLActionException) t;%0A
+) t).errorCode() : 5000;%0A%0A        // @formatter:off%0A        builder%0A            .startObject()%0A                .startObject(%22error%22)%0A        
     
@@ -2913,39 +2913,32 @@
             
-builder
 .field(%22
 code%22, sqlAc
@@ -2929,47 +2929,41 @@
 ld(%22
-code%22, sqlActionException.errorCod
+message%22, userFriendlyMessag
 e(
+t
 ))
-;
 %0A   
@@ -2963,33 +2963,25 @@
 t))%0A        
-%7D else %7B%0A
+ 
             
@@ -2975,32 +2975,24 @@
             
- builder
 .field(%22code
@@ -2998,14 +2998,18 @@
 e%22, 
-5000);
+errorCode)
 %0A   
@@ -3017,19 +3017,16 @@
     
-%7D%0A%0A
         
 buil
@@ -3013,39 +3013,32 @@
                 
-builder
 .endObject();%0A%0A 
@@ -3035,25 +3035,24 @@
 ject();%0A
-%0A
         
 if (t !=
@@ -3047,121 +3047,55 @@
     
-if (t != null && channel.request().paramAsBoolean(%22error_trace%22, false)%0A            && sqlActionException != null
+// @formatter:on%0A%0A        if (includeErrorTrace
 ) %7B%0A
@@ -3178,32 +3178,39 @@
       %7D%0A        
+return 
 builder.endObjec
@@ -3218,32 +3218,8 @@
 ();%0A
-        return builder;%0A
     

Remove redundant null checks from CrateThrowableRestResponse