IN: errors USING: errors help kernel kernel-internals ; HELP: error { $description "Global variable holding most recently thrown error." } { $notes "Only updated by " { $link throw } ", not " { $link rethrow } "." } ; HELP: error-continuation { $description "Global variable holding current continuation of most recently thrown error." } { $notes "Only updated by " { $link throw } ", not " { $link rethrow } "." } ; HELP: >c { $values { "continuation" "a continuation" } } { $description "Pushes an exception handler continuation on the catch stack. The continuation must have been reified by " { $link callcc1 } "." } ; HELP: c> { $values { "continuation" "a continuation" } } { $description "Pops an exception handler continuation from the catch stack." } ; HELP: throw ( error -- * ) { $values { "error" "an object" } } { $description "Saves the current continuation in the " { $link error-continuation } " global variable and throws an error. Execution does not continue at the point after the " { $link throw } " call. Rather, the innermost catch block is invoked, and execution continues at that point." } { $see-also rethrow } ; HELP: catch { $values { "try" "a quotation" } { "error/f" "an object" } } { $description "Calls the " { $snippet "try" } " quotation. If an error is thrown in the dynamic extent of the quotation, restores the datastack and pushes the error. If the quotation returns successfully, outputs " { $link f } " without restoring the datastack." } { $notes "This word cannot differentiate between the case of " { $link f } " being thrown, and no error being thrown. You should never throw " { $link f } ", and you should also use other error handling combinators where possible." } { $see-also cleanup recover } ; HELP: cleanup { $values { "try" "a quotation" } { "cleanup" "a quotation" } } { $description "Calls the " { $snippet "try" } " quotation. If an exception is thrown in the dynamic extent of the " { $snippet "try" } " quotation, restores the datastack, calls the " { $snippet "cleanup" } " quotation, and rethrows the error. If the " { $snippet "try" } " quotation returns successfully, calls the " { $snippet "cleanup" } " quotation without restoring the datastack." } { $see-also catch recover } ; HELP: recover { $values { "try" "a quotation" } { "recovery" "a quotation with stack effect " { $snippet "( error -- )" } } } { $description "Calls the " { $snippet "try" } " quotation. If an exception is thrown in the dynamic extent of the " { $snippet "try" } " quotation, restores the datastack and calls the " { $snippet "recovery" } " quotation to handle the error." } { $see-also catch cleanup } ; HELP: rethrow { $values { "error" "an object" } } { $description "Throws an error without saving the current continuation in the " { $link error-continuation } " global variable. This is done so that inspecting the error stacks sheds light on the original cause of the exception, rather than the point where it was rethrown." } { $examples "This word definition attempts to convert a hexadecimal literal string to an integer, and outputs " { $link f } " if there is an error:" { $code ": catch-hex> ( str -- n/f )" " [ hex> ] [ [ drop f ] when ] catch ;" } } ; HELP: condition { $values { "error" "an object" } { "restarts" "a sequence of pairs" } { "restart" "an object" } } { $description "Throws a restartable error. The " { $snippet "restarts" } " parameter is a sequence of pairs where the first element in each pair is a human-readable description and the second is an arbitrary object. If the error reaches the top-level error handler, the user will be presented with the list of possible restarts, and upon invoking one with the " { $link :res } " word, execution will continue after the call to " { $link condition } " with the object associated to the chosen restart on the stack." } { $examples "Try invoking one of the two restarts which are offered after the below code throws an error:" { $code ": restart-test" " \"Oops!\" { { \"One\" 1 } { \"Two\" 2 } } condition" " \"You restarted: \" write . ;" "restart-test" } } ; HELP: compute-restarts { $values { "error" "an object" } { "seq" "a sequence" } } { $description "Outputs a sequence of triples, where each triple consists of a human-readable string, an object, and a continuation. Resuming a continuation with the corresponding object restarts execution immediately after the corresponding call to " { $link condition } "." $terpri "This word recursively travels up the delegation chain to collate restarts from nested and wrapped conditions." } ;