{"slug": "anyhow", "name": "anyhow", "category": "dev-libs", "category_name": "Libraries and frameworks", "description": "", "recommenders": 6, "commenters": 16, "warners": 5, "score": 0.823, "rising": -1.96, "first": "2025-11-13", "latest": "2026-08-20", "why": "Or just go with Anyhow until you find a need for something else.", "why_is_quote": true, "has_verdict": false, "sentiment": {"recommend": 6, "neutral": 4, "compare": 1, "warn": 5}, "spark": [1, 1, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0], "listed": true, "loved": [], "caveat": "", "short_quote": "Or just go with Anyhow until you find a need for something else.", "kind": "", "icon": false, "domain": null, "github_repo": null, "official_url": "https://github.com/dtolnay/anyhow", "pricing": "", "aliases": ["anyhow"], "verdict": null, "praise": [{"label": "", "summary": "", "quotes": [{"id": 772186240, "item_id": 48261640, "url": "https://news.ycombinator.com/item?id=48261640", "by": "dwattttt", "date": "2026-05-24", "version": null, "stance": "recommend", "quote": "I use anyhow for this", "excerpt": "I guess you might have to if you need to use a library someone's written that doesn't implement the standard. Writing primarily applications, I couldn't tell you what error handling frameworks my dependencies are using: I literally don't know, and haven't needed to know in order to display, fail, or succeed. EDIT to add: I use anyhow for this, so I should also add \"add context to an error when I fall\" to the list of ", "context": "", "use_case": "", "switched_from": "", "story": "Migrating from Go to Rust"}, {"id": 772179104, "item_id": 48261194, "url": "https://news.ycombinator.com/item?id=48261194", "by": "ViewTrick1002", "date": "2026-05-24", "version": null, "stance": "recommend", "quote": "Or just go with Anyhow until you find a need for something else.", "excerpt": "They all convert seamlessly, and the enums make the branches explicit. Don't even need to check the documentation to find which errors supposedly exists like in Go with its errors.Is, errors.As, wrapping and what not. An easy rule before you make a knowledge based choice is thiserror for libraries, helping you create the standard library error types and anyhow for applications, easy strings you bubble up. Or just go ", "context": "", "use_case": "application error handling", "switched_from": "", "story": "Migrating from Go to Rust"}, {"id": 744789825, "item_id": 46549364, "url": "https://news.ycombinator.com/item?id=46549364", "by": "bccdee", "date": "2026-01-08", "version": null, "stance": "recommend", "quote": "thiserror\u00b9 for libraries, anyhow\u00b2 for applications", "excerpt": "> There is good reason why even the languages that support defined error sets have trended back to using open-ended constructs. Rust does it that way & has never trended in any other direction. The generally-accepted wisdom is \"thiserror\u00b9 for libraries, anyhow\u00b2 for applications\"\u2014i.e., any error that's liable to be handled by a machine should be an enum of exhaustively-matchable error kinds, whereas anything that's ju", "context": "", "use_case": "Rust error handling", "switched_from": "", "story": "An Honest Review of Go"}, {"id": 743910225, "item_id": 46494389, "url": "https://news.ycombinator.com/item?id=46494389", "by": "tison", "date": "2026-01-04", "version": null, "stance": "recommend", "quote": "exn benefits something from anyhow", "excerpt": "This is the pull request of this post: https://github.com/fast/fast.github.io/pull/12 See comments like https://github.com/fast/fast.github.io/pull/12#discussion_r2659513332 Quote my comment in the other thread: > That said, exn benefits something from anyhow: https://github.com/fast/exn/pull/18, and we feed back our practices to error-stack where we come from: https://github.com/hashintel/hash/issues/667#issuecommen", "context": "", "use_case": "", "switched_from": "", "story": "Stop Forwarding Errors, Start Designing Them"}, {"id": 742632560, "item_id": 46414535, "url": "https://news.ycombinator.com/item?id=46414535", "by": "burntsushi", "date": "2025-12-28", "version": null, "stance": "recommend", "quote": "anyhow` and `thiserror` have been around for a number of years now and shows no signs of going away", "excerpt": "> It was `std` only and linked to a concept of backtraces, which made it a non-started for embedded. It just seemed to me that it was a bad idea ever to use it in a library and that it would harm embedded users. It was never linked to backtraces. And if you used `std::error::Error` in a library that you also wanted to support in no-std mode, then you just didn't implement the `std::error::Error` trait when the `std` ", "context": "", "use_case": "", "switched_from": "", "story": "Rust Errors Without Dependencies"}]}], "caveats": [{"label": "", "summary": "", "quotes": [{"id": 790084289, "item_id": 49380268, "url": "https://news.ycombinator.com/item?id=49380268", "by": "echelon", "date": "2026-08-20", "version": null, "stance": "warn", "quote": "I wouldn't want to see anyhow, thiserror, anything opinionated", "excerpt": "Good ideas are pulled into the standard library. https://crates.io/crates/once_cell https://doc.rust-lang.org/std/cell/struct.OnceCell.html Not everything should be eligible for this treatment. Certainly not an HTTP library or something without extremely widespread applicability. Nearly all of my projects used once_cell, so it's good to see that pulled in. I wouldn't want to see anyhow, thiserror, anything opinionate", "context": "", "use_case": "", "switched_from": "", "story": "Malicious Rust Crate Arrayref Runs a Build-Time Payload"}, {"id": 760653856, "item_id": 47540866, "url": "https://news.ycombinator.com/item?id=47540866", "by": "uzerfcwn", "date": "2026-03-27", "version": null, "stance": "warn", "quote": "or just use opaque errors like the anyhow crate. The downside is that these approaches lose type information", "excerpt": "I don't know what quotemstr was specifically talking about, but here's my own take. The ideal error handling is inferred algebraic effects like in Koka[1]. This allows you to add a call to an error-throwing function 15 layers down the stack and it's automatically propagated into the type signatures of all functions up the stack (and you can see the inferred effects with a language server or other tooling, similar to ", "context": "", "use_case": "Opaque error handling", "switched_from": "", "story": "An Incoherent Rust"}, {"id": 743892226, "item_id": 46493264, "url": "https://news.ycombinator.com/item?id=46493264", "by": "larusso", "date": "2026-01-04", "version": null, "stance": "warn", "quote": "just as broken as thiserror and anyhow", "excerpt": "Error handling in rust is the number one frustration. I rewrote my errors multiple time. I used error_chain which looked good on paper but was just as broken as thiserror and anyhow. The missing piece is already the fact that no one really defines how to write good and meaningful error types for the different audiences. Even the article described some cases that are highly implementation specific. I will take a look ", "context": "Rust developer", "use_case": "Rust error handling", "switched_from": "", "story": "Stop Forwarding Errors, Start Designing Them"}, {"id": 742630289, "item_id": 46414393, "url": "https://news.ycombinator.com/item?id=46414393", "by": "osiris88", "date": "2025-12-28", "version": null, "stance": "warn", "quote": "Nowadays I try to avoid all of these libraries (failure, anyhow, thiserror, etc.)", "excerpt": "I've been using rust for 8+ years, I remember the experiments around `failure` crate, a precursor to anyhow if I remember right... and then eyre, and then thiserror... It just felt like too much churn and each one offered barely any distinction to the previous. Additionally, the `std::error::Error` trait was very poorly designed when it was initially created. It was `std` only and linked to a concept of backtraces, w", "context": "", "use_case": "", "switched_from": "", "story": "Rust Errors Without Dependencies"}]}], "who": [], "tags": [], "use_cases": ["rust error handling", "application error handling", "opaque error handling", "formatting error chains", "error context in rust"], "compared": [{"slug": "thiserror", "name": "thiserror", "co": 13, "switched_from": 0, "switched_to": 0}], "makers": [], "threads": [{"url": "https://news.ycombinator.com/item?id=46408365", "title": "Rust Errors Without Dependencies", "mentions": 4}, {"url": "https://news.ycombinator.com/item?id=48259808", "title": "Migrating from Go to Rust", "mentions": 3}, {"url": "https://news.ycombinator.com/item?id=46491051", "title": "Stop Forwarding Errors, Start Designing Them", "mentions": 3}, {"url": "https://news.ycombinator.com/item?id=49374269", "title": "Malicious Rust Crate Arrayref Runs a Build-Time Payload", "mentions": 1}, {"url": "https://news.ycombinator.com/item?id=47490648", "title": "An Incoherent Rust", "mentions": 1}, {"url": "https://news.ycombinator.com/item?id=46737447", "title": "Banned C++ Features in Chromium", "mentions": 1}], "sentiment_by_month": {"2025-11": {"neutral": 1, "recommend": 1, "warn": 1}, "2025-12": {"compare": 1, "warn": 1, "recommend": 1, "neutral": 1}, "2026-01": {"warn": 1, "recommend": 2, "neutral": 1}, "2026-02": {}, "2026-03": {"warn": 1}, "2026-04": {}, "2026-05": {"recommend": 2, "neutral": 1}, "2026-06": {}, "2026-07": {}, "2026-08": {"warn": 1}, "2026-09": {}, "2026-10": {}}, "versions": [], "version_unnamed": 0, "family_ref": null, "runs_on": null, "lines": [], "quotes": [{"id": 790084289, "item_id": 49380268, "url": "https://news.ycombinator.com/item?id=49380268", "by": "echelon", "date": "2026-08-20", "version": null, "stance": "warn", "quote": "I wouldn't want to see anyhow, thiserror, anything opinionated", "excerpt": "Good ideas are pulled into the standard library. https://crates.io/crates/once_cell https://doc.rust-lang.org/std/cell/struct.OnceCell.html Not everything should be eligible for this treatment. Certainly not an HTTP library or something without extremely widespread applicability. Nearly all of my projects used once_cell, so it's good to see that pulled in. I wouldn't want to see anyhow, thiserror, anything opinionate", "context": "", "use_case": "", "switched_from": "", "story": "Malicious Rust Crate Arrayref Runs a Build-Time Payload"}, {"id": 772190321, "item_id": 48261895, "url": "https://news.ycombinator.com/item?id=48261895", "by": "LoganDark", "date": "2026-05-24", "version": null, "stance": "neutral", "quote": "Anyhow is perhaps the closest one to another paradigm", "excerpt": "thiserror and anyhow are just std::error with extra steps. Note that io::error is just a specific std::error. The entire point in Rust is that you wrap Error impls with other Error impls, or translate one impl into another using a match. I've found this is far more flexible and verifiable than most other languages, because if you craft your error types with enough rigor, you can basically have a complete semantic bac", "context": "", "use_case": "Rust error handling", "switched_from": "", "story": "Migrating from Go to Rust"}, {"id": 772186240, "item_id": 48261640, "url": "https://news.ycombinator.com/item?id=48261640", "by": "dwattttt", "date": "2026-05-24", "version": null, "stance": "recommend", "quote": "I use anyhow for this", "excerpt": "I guess you might have to if you need to use a library someone's written that doesn't implement the standard. Writing primarily applications, I couldn't tell you what error handling frameworks my dependencies are using: I literally don't know, and haven't needed to know in order to display, fail, or succeed. EDIT to add: I use anyhow for this, so I should also add \"add context to an error when I fall\" to the list of ", "context": "", "use_case": "", "switched_from": "", "story": "Migrating from Go to Rust"}, {"id": 772179104, "item_id": 48261194, "url": "https://news.ycombinator.com/item?id=48261194", "by": "ViewTrick1002", "date": "2026-05-24", "version": null, "stance": "recommend", "quote": "Or just go with Anyhow until you find a need for something else.", "excerpt": "They all convert seamlessly, and the enums make the branches explicit. Don't even need to check the documentation to find which errors supposedly exists like in Go with its errors.Is, errors.As, wrapping and what not. An easy rule before you make a knowledge based choice is thiserror for libraries, helping you create the standard library error types and anyhow for applications, easy strings you bubble up. Or just go ", "context": "", "use_case": "application error handling", "switched_from": "", "story": "Migrating from Go to Rust"}, {"id": 760653856, "item_id": 47540866, "url": "https://news.ycombinator.com/item?id=47540866", "by": "uzerfcwn", "date": "2026-03-27", "version": null, "stance": "warn", "quote": "or just use opaque errors like the anyhow crate. The downside is that these approaches lose type information", "excerpt": "I don't know what quotemstr was specifically talking about, but here's my own take. The ideal error handling is inferred algebraic effects like in Koka[1]. This allows you to add a call to an error-throwing function 15 layers down the stack and it's automatically propagated into the type signatures of all functions up the stack (and you can see the inferred effects with a language server or other tooling, similar to ", "context": "", "use_case": "Opaque error handling", "switched_from": "", "story": "An Incoherent Rust"}, {"id": 747871088, "item_id": 46741943, "url": "https://news.ycombinator.com/item?id=46741943", "by": "drysine", "date": "2026-01-24", "version": null, "stance": "neutral", "quote": "Where people use things like anyhow.", "excerpt": "> like Rust Where people use things like anyhow.[0] [0] https://docs.rs/anyhow/latest/anyhow/", "context": "", "use_case": "", "switched_from": "", "story": "Banned C++ Features in Chromium"}, {"id": 744789825, "item_id": 46549364, "url": "https://news.ycombinator.com/item?id=46549364", "by": "bccdee", "date": "2026-01-08", "version": null, "stance": "recommend", "quote": "thiserror\u00b9 for libraries, anyhow\u00b2 for applications", "excerpt": "> There is good reason why even the languages that support defined error sets have trended back to using open-ended constructs. Rust does it that way & has never trended in any other direction. The generally-accepted wisdom is \"thiserror\u00b9 for libraries, anyhow\u00b2 for applications\"\u2014i.e., any error that's liable to be handled by a machine should be an enum of exhaustively-matchable error kinds, whereas anything that's ju", "context": "", "use_case": "Rust error handling", "switched_from": "", "story": "An Honest Review of Go"}, {"id": 743910994, "item_id": 46494437, "url": "https://news.ycombinator.com/item?id=46494437", "by": "tison", "date": "2026-01-04", "version": null, "stance": "neutral", "quote": "That error type can then be used with `anyhow` or `exn`.", "excerpt": "I think they are almost compatible. `thiserror` helps you define the error type. That error type can then be used with `anyhow` or `exn`. Actually, we have been using thiserror + exn for a long time, and it works well. While later we realize that `struct ModuleError(String)` can easily implement Error without thiserror, we remove thiserror dependency for conciseness. `exn` can use `anyhow::Error` as its inner Error. ", "context": "", "use_case": "Rust error handling", "switched_from": "", "story": "Stop Forwarding Errors, Start Designing Them"}, {"id": 743910225, "item_id": 46494389, "url": "https://news.ycombinator.com/item?id=46494389", "by": "tison", "date": "2026-01-04", "version": null, "stance": "recommend", "quote": "exn benefits something from anyhow", "excerpt": "This is the pull request of this post: https://github.com/fast/fast.github.io/pull/12 See comments like https://github.com/fast/fast.github.io/pull/12#discussion_r2659513332 Quote my comment in the other thread: > That said, exn benefits something from anyhow: https://github.com/fast/exn/pull/18, and we feed back our practices to error-stack where we come from: https://github.com/hashintel/hash/issues/667#issuecommen", "context": "", "use_case": "", "switched_from": "", "story": "Stop Forwarding Errors, Start Designing Them"}, {"id": 743892226, "item_id": 46493264, "url": "https://news.ycombinator.com/item?id=46493264", "by": "larusso", "date": "2026-01-04", "version": null, "stance": "warn", "quote": "just as broken as thiserror and anyhow", "excerpt": "Error handling in rust is the number one frustration. I rewrote my errors multiple time. I used error_chain which looked good on paper but was just as broken as thiserror and anyhow. The missing piece is already the fact that no one really defines how to write good and meaningful error types for the different audiences. Even the article described some cases that are highly implementation specific. I will take a look ", "context": "Rust developer", "use_case": "Rust error handling", "switched_from": "", "story": "Stop Forwarding Errors, Start Designing Them"}, {"id": 742642784, "item_id": 46415174, "url": "https://news.ycombinator.com/item?id=46415174", "by": "burntsushi", "date": "2025-12-28", "version": null, "stance": "neutral", "quote": "I usually use `anyhow` to do that for me", "excerpt": "> I do think that `std::error::Error` is mostly pointless. That's a value judgment, and reasonable people can disagree. I took it as a statement of fact. It is a factual matter of whether `std::error::Error` has a point to it or not. And it definitively does. I use the error chain in just about every CLI application I've built. It's not even mostly pointless. It's incredibly useful and it provides an interoperable po", "context": "", "use_case": "Formatting error chains", "switched_from": "", "story": "Rust Errors Without Dependencies"}, {"id": 742634512, "item_id": 46414657, "url": "https://news.ycombinator.com/item?id=46414657", "by": "vsgherzi", "date": "2025-12-28", "version": null, "stance": "neutral", "quote": "This is more something I wanted to do and not something I recommend for everyone.", "excerpt": "Anyhow itself is still a dependency. This is more something I wanted to do and not something I recommend for everyone. Google took a similar approach in how they added rust for chrome. They don\u2019t use an error handling library.", "context": "", "use_case": "", "switched_from": "", "story": "Rust Errors Without Dependencies"}, {"id": 742632560, "item_id": 46414535, "url": "https://news.ycombinator.com/item?id=46414535", "by": "burntsushi", "date": "2025-12-28", "version": null, "stance": "recommend", "quote": "anyhow` and `thiserror` have been around for a number of years now and shows no signs of going away", "excerpt": "> It was `std` only and linked to a concept of backtraces, which made it a non-started for embedded. It just seemed to me that it was a bad idea ever to use it in a library and that it would harm embedded users. It was never linked to backtraces. And if you used `std::error::Error` in a library that you also wanted to support in no-std mode, then you just didn't implement the `std::error::Error` trait when the `std` ", "context": "", "use_case": "", "switched_from": "", "story": "Rust Errors Without Dependencies"}, {"id": 742630289, "item_id": 46414393, "url": "https://news.ycombinator.com/item?id=46414393", "by": "osiris88", "date": "2025-12-28", "version": null, "stance": "warn", "quote": "Nowadays I try to avoid all of these libraries (failure, anyhow, thiserror, etc.)", "excerpt": "I've been using rust for 8+ years, I remember the experiments around `failure` crate, a precursor to anyhow if I remember right... and then eyre, and then thiserror... It just felt like too much churn and each one offered barely any distinction to the previous. Additionally, the `std::error::Error` trait was very poorly designed when it was initially created. It was `std` only and linked to a concept of backtraces, w", "context": "", "use_case": "", "switched_from": "", "story": "Rust Errors Without Dependencies"}, {"id": 738496833, "item_id": 46156052, "url": "https://news.ycombinator.com/item?id=46156052", "by": "nu11ptr", "date": "2025-12-04", "version": null, "stance": "compare", "quote": "I believe `anyhow` can mostly do the same.", "excerpt": "> you sort of come to understand \"this goo at the end of the expression is just coercing the return value into whatever alternate goo the function signature dictates it needs\", which is not at all the same thing as careful error handling. I think the problem is Rust does a great job at providing the basic mechanics of errors, but then stops a bit short. First, I didn't realize until relatively recently that any `Stri", "context": "", "use_case": "", "switched_from": "", "story": "Thoughts on Go vs. Rust vs. Zig"}, {"id": 736901872, "item_id": 46056367, "url": "https://news.ycombinator.com/item?id=46056367", "by": "dlahoda", "date": "2025-11-26", "version": null, "stance": "warn", "quote": "no anyhow", "excerpt": "end result is here https://zo-devnet.n1.xyz/docs - well documented strongly typed errors for API. most eveolved https://zo-devnet.n1.xyz/docs#tag/default/post/action - mixes binary encoding, headers, and numeric errors embeeding (http goes to binary tx format). all strongly typed without duplicated boilerplate. inside - ad hoc error assembly - display_doc,derive_more, backtrace - no anyhow, not thiserror, no snafu. f", "context": "", "use_case": "", "switched_from": "", "story": "Implementing Rust newtype for errors in axum"}, {"id": 735634368, "item_id": 45977148, "url": "https://news.ycombinator.com/item?id=45977148", "by": "cube00", "date": "2025-11-19", "version": null, "stance": "recommend", "quote": "even adding in some anyhow::context goes a long way", "excerpt": "> Not panicking code is tedious to write. Using the question mark operator [1] and even adding in some anyhow::context goes a long way to being able to fail fast and return an Err rather then panicking. Sure you need to handle Results all the way up the stack but it forces you to think about how those nested parts of your app will fail as you travel back up the stack. [1]: https://doc.rust-lang.org/rust-by-example/st", "context": "", "use_case": "error context in Rust", "switched_from": "", "story": "Cloudflare outage on November 18, 2025 post mortem"}, {"id": 734754612, "item_id": 45922163, "url": "https://news.ycombinator.com/item?id=45922163", "by": "virexdev", "date": "2025-11-13", "version": null, "stance": "neutral", "quote": "taught me a lot about thiserror / anyhow and why good context matters", "excerpt": "FAQ [?] why did you make this? [!] i wanted a small, fast, rust-based tree-like tool that was actually fun to build and mess with. while working on it i hit a bunch of interesting challenges: ownership issues, error handling, unicode alignment, and even building a simple interactive terminal UI. this is mostly a hobby project, but i think it\u2019s a nice little learning playground too. [?] what makes it interesting? [X] ", "context": "", "use_case": "", "switched_from": "", "story": "Canopy It's a fast rust CLI that prints directory trees"}]}