void (String methodName, String id, String parentId, String messageName, Throwable ex, long duration, String reason) { final Map<String, String> attrs = new LinkedHashMap<>(); try { attrs.put("name", methodName); attrs.put("id", id); attrs.put("nodeId", id); attrs.put("parentNodeId", parentId); if (duration > 0) { attrs.put("duration", Long.toString(duration)); } if (reason != null) { attrs.put("message", reason); } if (ex != null) { attrs.put("details", getTrace(ex)); } if (ex != null) { if (ex instanceof MultipleFailuresError && ((MultipleFailuresError)ex).hasFailures()) { for (Throwable assertionError : ((MultipleFailuresError)ex).getFailures()) { testFailure(methodName, id, parentId, messageName, assertionError, duration, reason); } } else if (ex instanceof AssertionFailedError && ((AssertionFailedError)ex).isActualDefined() && ((AssertionFailedError)ex).isExpectedDefined()) { attrs.put("expected", ((AssertionFailedError)ex).getExpected().getStringRepresentation()); attrs.put("actual", ((AssertionFailedError)ex).getActual().getStringRepresentation()); attrs.put("type", "comparisonFailure"); } else { Class<? extends Throwable> aClass = ex.getClass(); if (isComparisonFailure(aClass)) { try { String expected = (String)aClass.getMethod("getExpected").invoke(ex); String actual = (String)aClass.getMethod("getActual").invoke(ex); attrs.put("expected", expected); attrs.put("actual", actual); attrs.put("type", "comparisonFailure"); } catch (Throwable e) { e.printStackTrace(myPrintStream); } } } } } finally { myPrintStream.println(ServiceMessage.asString(messageName, attrs)); } }