Skip to content

rlbdv/murphy-clj

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

38 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

murphy (What could go wrong?)

NOTE: While we’d love for people to try this out, as long as the version is less than 1.0, we reserve the right (which we may well exercise) to change the API.

Consider:

(try
  (print-masterpiece)  ; Throws lp0-on-fire
  (finally
    (turn-off-light)))  ; Throws switch-broken

At this point, you’ll know that you need to fix your light switch, but have no idea that your printer is on fire. That’s because a throw from a finally clause simply discards any pending exception.

To preserve all of the failure information, we can use exception suppression, which is provided by newer versions of the JDK and write this instead:

(try!
  (print-masterpiece)  ; Throws lp0-on-fire
  (finally
    (turn-off-light)))  ; Throws lp0-on-fire, with switch-broken
                        ; available via (.getSuppressed lp0-on-fire).

As mentioned in the exception suppression documentation linked above, whether or not a suppressed exception is recorded or discarded depends on the constructor arguments for the original exception.

In any case, if an exception does contain suppressed exceptions, they should be displayed by the normal top-level JVM exception handler, assuming they make it that far.

Facilities

(try! …)

Behaves like the normal try, except that it supports multiple finally clauses which are executed in order, and if any given finally clause throws while an exception is already pending, the new exception will be suppressed via the Throwable addSuppressed method.

(with-open! [binding init …] …)

Behaves like the normal with-open except that exceptions thrown by any of the close methods will be suppressed. And of course any exception pending at the end of the cleanup will be thrown. It also allows destructuring.

(with-final …)

Configurable cleanup, suppressing exceptions, either on :error (any throw) or :always:

(with-final [foo (.acquire lock) :always .release
             {:keys [id kind] :as bar} (open something) :always .close
             baz {:foo foo :bar bar}]
  ...)

:error can be particularly useful in cases where normal cleanup must happen in a completely different scope.

(defn start-server [...]
  (with-final [foo (open-foo ...) :error .close
               bar (connect-bar ...) :error .disconnect
               ...]
    ...do many things...
    {:foo foo :bar bar ...}))

(defn stop-server [info]
  (with-final [_ (:foo info) :always .close
               _ (:bar info) :always .disconnect
               ...]
    true)

Contributing

You can run all of the existing tests (including lein test) with lein check-all.

All patches must be “signed off” by the author before official inclusion (see ./SIGNED-OFF-BY). If you like, git can can add the appropriate pseudo-header for you via the –signoff argument to commit, amend, etc.

License

This project is free software; unless otherwise specified below, you can redistribute it and/or modify it under the terms of (at your option) either of the following two licenses:

  1. The GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1, or (at your option) any later version: https://www.gnu.org/licenses/lgpl-2.1.html
  2. The Eclipse Public License; either version 1.0 or (at your option) any later version: http://www.eclipse.org/legal/epl-v10.html

Copyright © 2017-2018, 2020-2021 2025 Rob Browning <[email protected]>

The with-final function in .clj-kondo/hooks.clj, which is only needed by kondo for linting, is derived from the PuppetDB version as of

commit 0c03037f659edf13307bc190bdc44f014aeb4158 Author: Rob Browning <[email protected]> Date: Mon Apr 18 11:28:35 2022 -0500

(PDB-5484) Add clj-kondo dependency, cmd, and config

which was covered under the terms of the Apache License, Version 2.0, January 2004 (http://www.apache.org/licenses/).

About

Clojure library for better handling of bad situations

Topics

Resources

Contributing

Stars

Watchers

Forks

Packages

No packages published