{"id":16338771,"url":"https://github.com/rufoa/try-let","last_synced_at":"2025-10-30T22:03:17.574Z","repository":{"id":62434991,"uuid":"44942542","full_name":"rufoa/try-let","owner":"rufoa","description":"Better exception handling for Clojure let expressions","archived":false,"fork":false,"pushed_at":"2019-02-01T01:39:23.000Z","size":16,"stargazers_count":20,"open_issues_count":0,"forks_count":4,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-30T06:41:30.323Z","etag":null,"topics":["clojure","exception-handling"],"latest_commit_sha":null,"homepage":"","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rufoa.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-10-26T03:03:02.000Z","updated_at":"2024-08-08T00:32:33.000Z","dependencies_parsed_at":"2022-11-01T21:15:53.917Z","dependency_job_id":null,"html_url":"https://github.com/rufoa/try-let","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rufoa%2Ftry-let","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rufoa%2Ftry-let/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rufoa%2Ftry-let/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rufoa%2Ftry-let/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rufoa","download_url":"https://codeload.github.com/rufoa/try-let/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rufoa%2Ftry-let/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":258244303,"owners_count":22670727,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clojure","exception-handling"],"created_at":"2024-10-10T23:51:36.888Z","updated_at":"2025-10-30T22:03:17.504Z","avatar_url":"https://github.com/rufoa.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"try-let\n=======\n\n`try-let` is a Clojure macro designed to make handling some exceptions slightly nicer. It acts like `let`, but allows you to catch exceptions which may be thrown inside the binding vector. Exceptions thrown inside the body of the `try-let` are deliberately ignored.\n\n[![Build Status](https://travis-ci.org/rufoa/try-let.png?branch=master)](https://travis-ci.org/rufoa/try-let)\n\n## Installation ##\n\n`try-let` is in Clojars. To use it in a Leiningen project, add it to your project.clj dependencies:\n\n[![Clojars Project](https://clojars.org/try-let/latest-version.svg)](https://clojars.org/try-let)\n\nthen require `try-let` in your code:\n\n```clojure\n(ns my.example\n   (:require [try-let :refer [try-let]]))\n```\n\n## Motivation ##\n\nIt can be quite difficult to combine `try/catch` with `let` properly. Clojure pushes you towards one of two patterns, neither of which is ideal.\n\n```clojure\n(try\n   (let [value (func-that-throws)]\n      (act-on-value value))\n   (catch Exception e\n      (log/error e \"func-that-throws failed\")))\n```\n\nIn the above pattern, the scope of the `try/catch` is too great. In addition to `func-that-throws`, it also affects `act-on-value`.\n\n```clojure\n(let [value\n   (try (func-that-throws)\n      (catch Exception e (log/error e \"func-that-throws failed\")))]\n   (act-on-value value))\n```\n\nIn the above pattern, the scope of the `try/catch` is correct, affecting only `func-that-throws`, but when an exception is caught, `act-on-value` is evaluated regardless and must handle the exceptional case when `value` is nil.\n\n## Use ##\n\nWith `try-let`, we can instead do:\n\n```clojure\n(try-let [value (func-that-throws)]\n   (act-on-value value)\n   (catch Exception e\n      (log/error e \"func-that-throws failed\")))\n```\n\nThis allows the scope of the `try/catch` to be made as precise as possible, affecting only `func-that-throws`, and for evaluation to only proceed to `act-on-value` when `value` is obtained without error. In this way, `try-let` can be thought of as similar to `if-let`, where the body is only evaluated when the value of the binding vector is not nil.\n\nYou can have multiple `catch` stanzas for different exceptions. Much of what you'd expect to work in a normal `let` works:\n\n```clojure\n(try-let [val-1 (risky-func-1)\n          val-2 (risky-func-2 val-1)]\n   (log/info \"using values\" val-1 \"and\" val-2)\n   (* val-1 val-2)\n   (catch SpecificException _\n      (log/info \"using our fallback value instead\")\n      123)\n   (catch RuntimeException e\n      (log/error e \"Some other error occurred\")\n      (throw e))\n   (finally\n      (release-some-resource)))\n```\n\nAs an alternative, you can also put `catch` stanzas before other body expressions:\n\n```clojure\n(try-let [val-1 (risky-func-1)]\n  (catch Exception e\n    (log/error e \"Problem calling risky-func-1\")\n    0)\n  (try-let [val-2 (risky-func-2 val-1)]\n    (catch Exception e\n      (log/error e \"Problem calling risky-func-2\")\n      0)\n    (log/info \"using values\" val-1 \"and\" val-2)\n    (* val-1 val-2)))\n```\n\nThis makes the code logic more linear, where exceptions are handled closer to where they appear.\n\n## Slingshot support ##\n\nThere is also a `try+-let` macro which is compatible with [slingshot](https://github.com/scgilardi/slingshot)-style `catch` stanzas.\n\n## License ##\n\nCopyright © 2015-2019 [rufoa](https://github.com/rufoa)\n\nDistributed under the Eclipse Public License, the same as Clojure.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frufoa%2Ftry-let","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frufoa%2Ftry-let","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frufoa%2Ftry-let/lists"}