by 1718627440 | 2025-11-13 16:40:18+00:00
> The information about what the code was doing at the time an exception is thrown is implicit in the stack trace; the control flow is evident from line numbers, and with half-decent tooling, you can get hyperlinks from stack traces to source code.

Yes, but when you want to generate a diagnostic from that stack trace, you basically need to branch on all the possible internal states of internal layers at the point you catch the exception. So either you are incapable of generating detailed diagnostics or you essentially model the whole behaviour in a single place. Also the point where the error messages are generated is now completely removed from the place where the error did occur. This sounds like a nightmare to maintain and also means that the possible error messages aren't there as documentation when reading the code.

> If there's extra information you need to know about what's going on, you probably want to log it in non-error cases too, because it'll contextualize an error before the error occurs. You can't log on unwind for decisions made in routines that were invoked and returned from, and are no longer on the stack, in the error case.

I never said, that you can only use this for error cases. In fact what is an error and what not, is not defined in a single layer. For example a failure to open a file will be an error in a lower layer, but for an upper layer, that just means that it should try a different backend. Or a parsing error is fatal for the parser, but it might mean that the file format is different and the next parser should be tried, or that the data is from the network and can simply be discarded. An empty field can be normal data for the parser, but for the upper layer it is a fatal error.

> This is a choice you've made, not something inherent to unchecked exceptions. My argument is that you should not generally change the type of the error, and let polymorphism cover the abstraction.

Then either the reported errors are completely unspecific and unactionable or you are leaking implementation details. When you want to handle every error specifically and not leak implementation details, you need to handle it locally. When you want to know that you handle all cases, unchecked exceptions are unsatisfying. In my opinion programs should know what is going on and not just say "my bad, something happened I can't continue". That does not lead to robust systems and is neither suitable for user transparency nor for automated systems.

In my opinion software should either work completely automated or report to the end user. Software that needs sysadmins and operators at runtime is bad. That doesn't mean that that never occurs, it will, but it should be treated as a software defect.

> You get lots of error log messages for a single error.

Yes, but this describes the issue at different layers of the abstraction and in my eyes the whole thing is a single error message. Neither the fact that resource X isn't available nor the fact that some connection was refused, is a complete error description in isolation. You need both for a (complete) error description.

> Allocating on the failure path is only a real problem in OOM

Yes, but first I don't like my program to act bad in that case, and second, it is also a nightmare for predictable ownership semantics. I generally let the caller allocate the error/status information.

> Are you a Go user by any chance?

I have never used Go, not even tried, but what I read about the error mechanism appealed to me, because it matches what I think is a good idea and do anyway.

> Or if you're stuck with C++ (with or without exceptions), my commiserations.

I don't feel that unhappy with that approach. I think this is a design and architectural decision rather than a language issue.

> with or without exceptions

Currently, definitely without, because it isn't even available when targeting a free-standing implementation (embedded), but I also don't prefer them, it makes for unpredictable control flow and makes it hard to reason about sound-, complete- and exhaustiveness.

You seem to have the impression, that you can just panic and throw a stacktrace. That might work fine for a program running in the terminal and targeting developers, but it is not acceptable for end users nor for libraries. I also know programs that just output a stacktrace and crash. That is stupid. I mean I understand what is going on, because I am a developer, but first I am not familiar with every codebase I use, and second the average end user is not able to act on any of that and will be angry for good reason when it's documents are gone, data is corrupted or even the workflow is interrupted. I also don't perceive a network error, a file (system) issue or OOM to that rare for it to be acceptable, to just ignore it. I should be part of normal program behaviour.