Convert Exception to JSON

well, it is possible to do something like that, though you don't want to convert the exception object itself, but rather the message it has within, with a format you design, something like:

// […]
} catch (Exception ex) {
    Gson gson = new Gson();
    Map<String, String> exc_map = new HashMap<String, String>();
    exc_map.put("message", ex.toString());
    exc_map.put("stacktrace", getStackTrace(ex));
    System.out.println(gson.toJson(exc_map));
}

with getStackTrace() defined as suggests that answer:

public static String getStackTrace(final Throwable throwable) {
     final StringWriter sw = new StringWriter();
     final PrintWriter pw = new PrintWriter(sw, true);
     throwable.printStackTrace(pw);
     return sw.getBuffer().toString();
}

In theory, you could also iterate over the elements in a stack trace and generate something that looks like:

{ "NullPointerException" :
    { "Exception in thread \"main\" java.lang.NullPointerException",
        { 
          "Book.java:16" : "com.example.myproject.Book.getTitle",
          "Author.java:25" : "at com.example.myproject.Author.getBookTitles",
          "Bootstrap.java:14" : "at com.example.myproject.Bootstrap.main()"
        }
    },
  "Caused By" :
    { "Exception in thread \"main\" java.lang.NullPointerException",
        { 
          "Book.java:16" : "com.example.myproject.Book.getTitle",
          "Author.java:25" : "at com.example.myproject.Author.getBookTitles",
          "Bootstrap.java:14" : "at com.example.myproject.Bootstrap.main()"
        }
    }
}

You can iterate the exception like this:

catch (Exception cause) {
    StackTraceElement elements[] = cause.getStackTrace();
    for (int i = 0, n = elements.length; i < n; i++) {       
        System.err.println(elements[i].getFileName()
            + ":" + elements[i].getLineNumber() 
            + ">> "
            + elements[i].getMethodName() + "()");
    }
}

Below is the routine to convert an Exception to JSON in a standardized way:

public static JSONObject convertToJSON(Throwable e, String context) throws Exception {
    JSONObject responseBody = new JSONObject();
    JSONObject errorTag = new JSONObject();
    responseBody.put("error", errorTag);

    errorTag.put("code", 400);
    errorTag.put("context", context);

    JSONArray detailList = new JSONArray();
    errorTag.put("details", detailList);

    Throwable nextRunner = e;
    List<ExceptionTracer> traceHolder = new ArrayList<ExceptionTracer>();
    while (nextRunner!=null) {
        Throwable runner = nextRunner;
        nextRunner = runner.getCause();

        detailObj.put("code", runner.getClass().getName());
        String msg =  runner.toString();
        detailObj.put("message",msg);

        detailList.put(detailObj);
    }

    JSONArray stackList = new JSONArray();
    for (StackTraceElement ste : e.getStackTrace()) {
        stackList.put(ste.getFileName() + ": " + ste.getMethodName()
               + ": " + ste.getLineNumber());
    }
    errorTag.put("stack", stackList);

    return responseBody;
}

You can find the complete open source library that implements this at: Purple JSON Utilities. This library supports the JSON Objects as well as the exceptions.

This produces a JSON structure of this form:

{
   "error": {
      "code": "400",
      "message": "main error message here",
      "target": "approx what the error came from",
      "details": [
         {
            "code": "23-098a",
            "message": "Disk drive has frozen up again.  It needs to be replaced",
            "target": "not sure what the target is"
         }
      ],
      "innererror": {
         "trace": [ ... ],
         "context": [ ... ]
      }
   }
}

This is the format proposed by the OASIS data standard OASIS OData and seems to be the most standard option out there, however there does not seem to be high adoption rates of any standard at this point.

The details are discussed in my blog post on Error Handling in JSON REST API