String (@Nullable String message, @Nullable Throwable cause) { StringBuilder buffer = new StringBuilder(); if (message != null) { buffer.append(message); } boolean first = true; for (Throwable t = cause; t != null; t = t.getCause()) { final String m = t.getLocalizedMessage(); if (m == null) { continue; } if (first) { first = false; // do not append same exception.message twice if (m.equals(message)) { continue; } } else if (buffer.length() > 0) { buffer.append("\n"); } buffer.append(m); } return buffer.toString(); }