// TODO: subclass RuntimeException and use Meta instead of DynamicObject static class PersistableThrowable extends DynamicObject { S className; S msg; S stacktrace; settable transient Throwable actualThrowable; *() {} *(Throwable e) { actualThrowable = e; if (e == null) className = "Crazy Null Error"; else { className = getClassName(e).replace('/', '.'); msg = e.getMessage(); stacktrace = getStackTrace_noRecord(e); } } public S toString() { ret nempty(msg) ? className + ": " + msg : className; } RuntimeException asRuntimeException() { if (actualThrowable != null) ret main asRuntimeException(actualThrowable); ret new Fail(this); } }