srecord noeq TimeoutException(double timeoutSeconds, O function, Thread thread) extends RuntimeException { @Override public S getMessage() { ret "Timeout after " + iceil(timeoutSeconds) + "s by " + shorten_str(function); } StackTraceElement[] innerStackTrace() { ret thread.getStackTrace(); } public cached Cause getCause() { ret new Cause; } class Cause > Throwable { *() { super("Still calculating", null, false, true); setStackTrace(innerStackTrace()); } } }