(call-with-handler handler thunk)
Run thunk
, using handler
to handle any exceptions raised.
Prefer to use with-handlers
instead of this function.
Note that the handler will be used for all exceptions, so you must
be careful to rethrow
exceptions that you can't handle.
Run `thunk`, using `handler` to handle any exceptions raised. Prefer to use `with-handlers` instead of this function. Note that the handler will be used for *all* exceptions, so you must be careful to `rethrow` exceptions that you can't handle.
(call-with-restarts make-restarts thunk)
This is an advanced function. Prefer with-restarts
where possible.
Run thunk
within a dynamic extent in which make-restarts
adds to
the list of current restarts. If an exception is thrown, then
make-restarts
will be invoked, and must return a list of restarts
applicable to this exception. If no exception is thrown, then
make-restarts
will not be invoked.
For example:
(call-with-restarts
(fn [ex] [(make-restart :use-value
"Use this value"
#(read-form ex)
identity)])
(^:once fn []
(/ 1 0)))
You should usually use the with-restarts
macro, but if you need to
dynamically vary your restarts depending on the type of exception
that is thrown, call-with-restarts
will let you register restarts
only after the exception has been thrown. Generally you should use
the :applicable?
property of the with-restarts
macro, but using
call-with-restarts
lets you do things like this:
(defn resolve [symbol]
(call-with-restarts
(fn [ex]
(for [namespace (all-ns)
:when (ns-resolve namespace symbol)]
(make-restart (keyword (str "use-" namespace))
(str "Resolve value from " namespace)
(constantly nil)
#(ns-resolve namespace symbol))))
(^:once fn []
(resolve symbol))))
Which provides a restart for each namespace that has a var with the correct name.
This is an advanced function. Prefer `with-restarts` where possible. Run `thunk` within a dynamic extent in which `make-restarts` adds to the list of current restarts. If an exception is thrown, then `make-restarts` will be invoked, and must return a list of restarts applicable to this exception. If no exception is thrown, then `make-restarts` will not be invoked. For example: (call-with-restarts (fn [ex] [(make-restart :use-value "Use this value" #(read-form ex) identity)]) (^:once fn [] (/ 1 0))) You should usually use the `with-restarts` macro, but if you need to dynamically vary your restarts depending on the type of exception that is thrown, `call-with-restarts` will let you register restarts only after the exception has been thrown. Generally you should use the `:applicable?` property of the `with-restarts` macro, but using `call-with-restarts` lets you do things like this: (defn resolve [symbol] (call-with-restarts (fn [ex] (for [namespace (all-ns) :when (ns-resolve namespace symbol)] (make-restart (keyword (str "use-" namespace)) (str "Resolve value from " namespace) (constantly nil) #(ns-resolve namespace symbol)))) (^:once fn [] (resolve symbol)))) Which provides a restart for each namespace that has a var with the correct name.
Evaluate a form, in the most relevant way.
This function will be dynamically rebound by whatever tooling is currently active, to properly wrap evaluation.
Evaluate a form, in the most relevant way. This function will be dynamically rebound by whatever tooling is currently active, to properly wrap evaluation.
(find-restart restart)
Return the first dynamically-bound restart with the provided name.
If passed an instance of Restart
, search by equality.
Return the first dynamically-bound restart with the provided name. If passed an instance of `Restart`, search by equality.
(find-restarts restart)
Return a list of all dynamically-bound restarts with the provided
name. If passed an instance of Restart
, search by equality.
Return a list of all dynamically-bound restarts with the provided name. If passed an instance of `Restart`, search by equality.
(invoke-restart restart & args)
Use the provided restart, with the given arguments. The restart
provided can be a name, in which case it will be looked up and the
most recently-bound matching restart will be used. If an instance of
Restart
is provided, it must be bound higher on the call-stack.
Always throws an exception, will never return normally.
Use the provided restart, with the given arguments. The restart provided can be a name, in which case it will be looked up and the most recently-bound matching restart will be used. If an instance of `Restart` is provided, it must be bound higher on the call-stack. Always throws an exception, will never return normally.
(list-restarts)
Return a list of all dynamically-bound restarts.
Return a list of all dynamically-bound restarts.
(make-restart name description make-arguments behaviour)
Create an instance of Restart
. When using the with-restarts
macro it's unnecessary to use this function. It is only necessary
when using call-with-restarts
to create restarts.
Create an instance of `Restart`. When using the `with-restarts` macro it's unnecessary to use this function. It is only necessary when using `call-with-restarts` to create restarts.
(prompt-user prompt)
(prompt-user prompt type & args)
Prompt the user for some input, in whatever way you can.
This function will be dynamically rebound by whatever tooling is currently active, to prompt the user appropriately.
Provide a type
in order to hint to tooling what kind of thing you
want to read. Legal values of type
are implementation dependent,
depending on the tooling in use. Tools should support a minimum of
:form
(to read a Clojure form), :file
(to read a filename), and
:options
(to choose an option from a list of options, provided as
the first argument after type
).
Prompt the user for some input, in whatever way you can. This function will be dynamically rebound by whatever tooling is currently active, to prompt the user appropriately. Provide a `type` in order to hint to tooling what kind of thing you want to read. Legal values of `type` are implementation dependent, depending on the tooling in use. Tools should support a minimum of `:form` (to read a Clojure form), `:file` (to read a filename), and `:options` (to choose an option from a list of options, provided as the first argument after `type`).
(read-and-eval-form ex)
Read a form from the user, and return the evaluated result for use as a restart's arguments.
Read a form from the user, and return the evaluated result for use as a restart's arguments.
(read-form ex)
Read an unevaluated form from the user, and return it for use as a restart's arguments;
Read an unevaluated form from the user, and return it for use as a restart's arguments;
(rethrow ex)
Rethrow an exception, without unwinding the stack any further. This
will invoke the nearest handler to handle the error. If no handlers
are available then this is equivalent to throw
, and the stack will
be unwound.
Rethrow an exception, without unwinding the stack any further. This will invoke the nearest handler to handle the error. If no handlers are available then this is equivalent to `throw`, and the stack will be unwound.
(unhandle-exception ex)
Rethrow an exception, unwinding the stack and propagating it as normal. This makes it seem as if the exception was never caught, but it may still be caught by handlers/restarts higher in the stack.
Rethrow an exception, unwinding the stack and propagating it as normal. This makes it seem as if the exception was never caught, but it may still be caught by handlers/restarts higher in the stack.
(with-handlers handlers & body)
Run body
, using handlers
to handle any exceptions which are
raised during body
's execution.
For example, here is how to use with-handlers
to replace
try/catch:
(with-handlers [(Exception ex (.getMessage ex))]
(/ 1 0))
;; => "Divide by zero"
Similarly to try/catch, multiple handlers can be defined for different exception types, and the first matching handler will be run to handle the exception.
Handlers can have only one of four outcomes:
invoke invoke-restart
, which will restart execution from the
specified restart
invoke rethrow
, which will either defer to a handler higher up
the call-stack, or propagate the exception via standard JVM
mechanisms.
return a value, which will be the value returned from the
with-handler-fn
form
throw an exception, which will be thrown as the result of the
with-handler-fn
form
Conceptually, options 1
and 2
process the error without
unwinding the stack, and options 3
and 4
unwind the stack up
until the handler.
If handler
is invoked, the dynamic var context will be set to be
as similar as possible to the dynamic context when with-hander-fn
is called. This simulates the fact that the handler conceptually
executes at a point much further up the call stack.
Any dynamic state captured in things other than vars (e.g.
ThreadLocal
s, open files, mutexes) will be in the state of the
with-restarts
execution nearest to the thrown exception.
Run `body`, using `handlers` to handle any exceptions which are raised during `body`'s execution. For example, here is how to use `with-handlers` to replace try/catch: (with-handlers [(Exception ex (.getMessage ex))] (/ 1 0)) ;; => "Divide by zero" Similarly to try/catch, multiple handlers can be defined for different exception types, and the first matching handler will be run to handle the exception. Handlers can have only one of four outcomes: 1. invoke `invoke-restart`, which will restart execution from the specified restart 2. invoke `rethrow`, which will either defer to a handler higher up the call-stack, or propagate the exception via standard JVM mechanisms. 3. return a value, which will be the value returned from the `with-handler-fn` form 4. throw an exception, which will be thrown as the result of the `with-handler-fn` form Conceptually, options `1` and `2` process the error without unwinding the stack, and options `3` and `4` unwind the stack up until the handler. If `handler` is invoked, the dynamic var context will be set to be as similar as possible to the dynamic context when `with-hander-fn` is called. This simulates the fact that the handler conceptually executes at a point much further up the call stack. Any dynamic state captured in things other than vars (e.g. `ThreadLocal`s, open files, mutexes) will be in the state of the `with-restarts` execution nearest to the thrown exception.
(with-restarts restarts & body)
Run body
, providing restarts
as dynamic restarts to handle
errors which occur while executing body
.
For example, a simple restart to use a provided value would look like this:
(with-restarts [(:use-value [value] value)]
(/ 1 0))
This would allow a handler to invoke (invoke-restart :use-value 10)
to recover from this exception, and to return 10
as the result of
the with-restarts
form.
In addition, restarts can have three extra attributes defined:
:applicable?
specifies a predicate which tests whether this
restart is applicable to this exception type. It defaults
to (fn [ex] true)
.
:describe
specifies a function which will convert the exception
into an explanation of what this restart will do. As a shortcut, you
may use a string literal instead, which will be converted into a
function returning that string. It defaults to (fn [ex] "")
.
:arguments
specifies a function which will return arguments for
this restart. This function is only ever used interactively, and
thus should prompt the user for any necessary information to invoke
this restart. It defaults to (fn [ex] nil)
.
Here is an example of the above restart using these attributes:
(with-restarts [(:use-value [value]
:describe "Provide a value to use."
:arguments #'read-unevaluated-value
value)]
(/ 1 0))
Restarts are invoked in the same dynamic context in which they were
defined. The stack is unwound to the level of the with-restarts
form, and the restart is invoked.
Multiple restarts with the same name can be defined, but the
"closest" one will be invoked by a call to invoke-restart
.
Restart names can be any value that is not an instance of
dont-give-up.core.Restart
, but it is recommended to use keywords
as names.
Run `body`, providing `restarts` as dynamic restarts to handle errors which occur while executing `body`. For example, a simple restart to use a provided value would look like this: (with-restarts [(:use-value [value] value)] (/ 1 0)) This would allow a handler to invoke `(invoke-restart :use-value 10)` to recover from this exception, and to return `10` as the result of the `with-restarts` form. In addition, restarts can have three extra attributes defined: 1. `:applicable?` specifies a predicate which tests whether this restart is applicable to this exception type. It defaults to `(fn [ex] true)`. 2. `:describe` specifies a function which will convert the exception into an explanation of what this restart will do. As a shortcut, you may use a string literal instead, which will be converted into a function returning that string. It defaults to `(fn [ex] "")`. 3. `:arguments` specifies a function which will return arguments for this restart. This function is only ever used interactively, and thus should prompt the user for any necessary information to invoke this restart. It defaults to `(fn [ex] nil)`. Here is an example of the above restart using these attributes: (with-restarts [(:use-value [value] :describe "Provide a value to use." :arguments #'read-unevaluated-value value)] (/ 1 0)) Restarts are invoked in the same dynamic context in which they were defined. The stack is unwound to the level of the `with-restarts` form, and the restart is invoked. Multiple restarts with the same name can be defined, but the "closest" one will be invoked by a call to `invoke-restart`. Restart names can be any value that is not an instance of `dont-give-up.core.Restart`, but it is recommended to use keywords as names.
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close