{"id":16370896,"url":"https://github.com/liquidz/merr","last_synced_at":"2026-03-07T02:33:01.042Z","repository":{"id":32685307,"uuid":"135415706","full_name":"liquidz/merr","owner":"liquidz","description":":fire: Minimal and good enough error handling library for Clojure/ClojureScript","archived":false,"fork":false,"pushed_at":"2024-04-27T01:34:35.000Z","size":118,"stargazers_count":63,"open_issues_count":0,"forks_count":1,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-09-27T02:00:55.400Z","etag":null,"topics":["clojure","clojurescript","error-handling"],"latest_commit_sha":null,"homepage":"","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"epl-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/liquidz.png","metadata":{"files":{"readme":"README.adoc","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-05-30T08:54:17.000Z","updated_at":"2025-03-26T14:39:38.000Z","dependencies_parsed_at":"2024-10-11T03:06:26.221Z","dependency_job_id":"89d2d9db-5cfe-4495-9738-d5fa2ef06098","html_url":"https://github.com/liquidz/merr","commit_stats":{"total_commits":179,"total_committers":1,"mean_commits":179.0,"dds":0.0,"last_synced_commit":"6969d933f77b3b9778c61666b0c7a5e3594c65c9"},"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"purl":"pkg:github/liquidz/merr","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/liquidz%2Fmerr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/liquidz%2Fmerr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/liquidz%2Fmerr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/liquidz%2Fmerr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/liquidz","download_url":"https://codeload.github.com/liquidz/merr/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/liquidz%2Fmerr/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30206070,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-06T19:07:06.838Z","status":"online","status_checked_at":"2026-03-07T02:00:06.765Z","response_time":53,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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","clojurescript","error-handling"],"created_at":"2024-10-11T03:06:23.748Z","updated_at":"2026-03-07T02:33:00.652Z","avatar_url":"https://github.com/liquidz.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"= merr\n\nimage:https://github.com/liquidz/merr/workflows/test/badge.svg[\"GitHub Actions for test workflow\", link=\"https://github.com/liquidz/merr/actions?query=workflow%3Atest\"]\nimage:https://github.com/liquidz/merr/workflows/lint/badge.svg[\"GitHub Actions for lint workflow\", link=\"https://github.com/liquidz/merr/actions?query=workflow%3Alint\"]\nimage:https://github.com/liquidz/merr/workflows/dependencies/badge.svg[\"GitHub Actions for dependencies workflow\", link=\"https://github.com/liquidz/merr/actions?query=workflow%3Adependencies\"]\nimage:https://codecov.io/gh/liquidz/merr/branch/master/graph/badge.svg[\"codecov\", link=\"https://codecov.io/gh/liquidz/merr\"]\n\nimage:https://img.shields.io/clojars/v/com.github.liquidz/merr.svg[\"Clojars Project\", link=\"https://clojars.org/com.github.liquidz/merr\"]\nimage:https://cljdoc.xyz/badge/com.github.liquidz/merr[\"cljdoc badge\", link=\"https://cljdoc.xyz/d/com.github.liquidz/merr/CURRENT\"]\n\nMinimal and good enough error handling library for Clojure/ClojureScript (and also Babashka/nbb)\n\nThis library is based on https://adambard.com/blog/acceptable-error-handling-in-clojure/[\"Good Enough\" error handling in Clojure].\n\n== Concept\n\n* Easy to imagine behavior\n* Minimum to remember\n** All usage and examples are documented in docstring\n\n[source,clojure]\n----\n(require '[merr.core :as merr])\n;; =\u003e nil\n\n;; for ClojureScript\n;; (require '[merr.core :as merr :include-macros true])\n\n(merr/let +err+ [foo 1\n                 bar (merr/error)\n                 baz (* bar 2)]\n  {:+err+ +err+ :foo foo :bar bar :baz baz})\n;; =\u003e {:+err+ (merr/error), :foo 1, :bar nil, :baz nil}\n----\n\n== Usage\n\n=== error record\n\n[source,clojure]\n----\n(defrecord MerrError [type message data cause])\n----\n\n=== `let`\n\n[source,clojure]\n----\n(merr/let err [a 10\n               b (inc a)\n               c (inc b)]\n  (if err\n    (merr/message err)\n    (str \"c = \" c)))\n;; =\u003e \"c = 12\"\n\n(merr/let err [a 10\n               b (merr/error {:message \"ERROR\"})\n               c (inc b)]\n  (if err\n    (merr/message err)\n    (str \"c = \" c)))\n;; =\u003e \"ERROR\"\n----\n\n=== `-\u003e`\n\n[source,clojure]\n----\n(merr/-\u003e 10 (+ 1) (- 1))\n;; =\u003e 10\n\n(merr/-\u003e 10 ((fn [_] (merr/error))) (- 1))\n;; =\u003e (merr/error)\n----\n\n=== `-\u003e\u003e`\n\n[source,clojure]\n----\n(merr/-\u003e\u003e 10 (+ 1) (- 1))\n;; =\u003e -10\n\n(merr/-\u003e\u003e 10 ((fn [_] (merr/error))) (- 1))\n;; =\u003e (merr/error)\n----\n\n=== `try`\n\n[source,clojure]\n----\n(merr/try (throw (ex-info \"ERROR\" {})))\n;; =\u003e merr/error?\n----\n\n== Custom error\n\nYou can specify any keywords as `:type`, but you may want to define and use specific `:type` of errors in your project.\nIn that case, `merr.helper` is useful.\n\n[source,clojure]\n----\n(require '[merr.helper :as merr.h])\n;; =\u003e nil\n\n(def custom-error (partial merr.h/typed-error ::custom-error-type))\n;; =\u003e var?\n\n(def custom-error? (partial merr.h/typed-error? ::custom-error-type))\n;; =\u003e var?\n\n(custom-error? (custom-error {:message \"custom error\"}))\n;; =\u003e true\n----\n\n`typed-error?` will check child error types, so you can define sub errors via `clojure.core/derive`.\n\n[source,clojure]\n----\n(derive ::sub-custom-error-type ::custom-error-type)\n;; =\u003e nil\n\n(custom-error? (merr/error {:type ::sub-custom-error-type}))\n;; =\u003e true\n----\n\n== Integration\n\n=== clj-kondo\n\nmerr provies clj-kondo's configuration and hooks.\nTo import configurations, run the following command.\n\n[source,console]\n----\nclj-kondo --no-warnings --lint \"$(clojure -Spath -Sdeps '{:deps {com.github.liquidz/merr {:mvn/version \"LATEST\"}}}')\"\n----\n\n== Support\n\n* Clojure\n* ClojureScript\n* https://github.com/babashka/babashka[Babashka]\n* https://github.com/babashka/nbb[nbb]\n\n== License\n\nCopyright © 2018-2022 https://twitter.com/uochan[Masashi Iizuka]\n\nDistributed under the Eclipse Public License either version 1.0 or (at your option) any later version.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fliquidz%2Fmerr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fliquidz%2Fmerr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fliquidz%2Fmerr/lists"}