vel0city 2 days ago

Gotta love reading a new to you codebase and seeing a bunch of

    catch (Exception ex) { };
littered throughout. Fixed the bug boss, close that ticket!
  • marklubi 2 days ago

    Totally agree with finding the source of the bug (there are some that I've spent weeks tracking down, there are millions of people that have my fixed code on their devices).

    If you've going to catch an error with a noop, there better be a comment explaining why you're not doing anything. It's not often, but sometimes, failing gracefully is just swallowing the error and moving on.

    • xboxnolifes 2 days ago

      At minimum, the error should be logged somewhere, and not just vanished. At least you get to know how frequently it occurs if/when that becomes meaningful to you.

      • marklubi a day ago

        In an app, if you have a string of network requests to your own services, there's no particular point in logging multiple (or any) 'no internet connection' errors. They won't make it to you, and having those doesn't provide much value. That's an end user problem.

        I have plenty of monitors to ensure my services are available (four-nines uptime for almost a decade). Internet unavailable errors are useless to log.

      • vel0city 2 days ago

        Exactly this. Log it, maybe at some really verbose log level, but please let me know it is hitting this point and a little bit of information of what the exception was.

        Also, only do it for exceptions you think might actually hit there and you're OK with quietly squashing. Otherwise, please let something else try and handle it.

  • lapetitejort 2 days ago

    I struggled with this recently. Someone was trying to patch up an error and force the program to continue. I asked him what was causing the error and he could only respond with how they were trying to patch it. I got so frustrated that I took on the error myself and fixed it with two lines of code.

    I think the problem is that some people think errors are supposed to happen. Just a cost of doing business. They can't be fixed, only mitigated.

  • sidewndr46 2 days ago

    On Error Resume Next

    The single line that magically fixes all Visual Basic 6 applications bugs

    • layer8 2 days ago

      Bash does it even by default. ;)

  • tshaddox 2 days ago

    Sometimes you're stuck using some API that throws exceptions for expected (i.e. non-exceptional) errors, and you really do want to do nothing additional when those expected errors occur.

    • devman0 2 days ago

      This is, in theory, the difference between checked and unchecked exceptions in languages that support such distinctions. Checked exceptions are basically part of the control flow and the API contract used for things that can happen but are not necessary programmer errors (IO Exceptions being the classic example). Whereas unchecked exceptions are supposed to be used for programming errors (think Illegal Arguments, Null Pointer, Array Index Out of Bounds). Unchecked also usually cover other fatal conditions like stack overflow or OOM. Checked, handle with care, Unchecked, let the stack unwind and fail fast.

    • vel0city 2 days ago

      Sure, I agree. I'd still prefer you properly scope it to just those expected exceptions, maybe put in some kind of debug level log related to it. The above code grabs every kind of exception and silently squashes it into oblivion.

  • Groxx 2 days ago

    especially Exception. Ugh. Gotta love those interrupt-ignorers.

    • layer8 2 days ago

      Unfortunately, it’s somewhat of a lost cause unless you control all the code. Even some OJDBC drivers swallow interrupts. I had to resort to application-specific interrupt flags.

  • eknkc 2 days ago

    Having a lint rule to disallow empty catch bodies has been a good practice for me. Sometimes you deliberately do it and even then I am forced to at least leave a `// ignore` there.

    • vel0city a day ago

      Absolutely, linter rules that expose such things are critical to fixing these things. And I add them to the PR linter to comment on PRs when I can to point out discussions about such things.

  • atoav 2 days ago

    Handling exceptions is interesting because in my experience a lot of it boils down to a social dimension:

    * if the input data field for a telephone number contains a country name do you communicate that error back to the source, if yes how and how often (assuming your source isn't a life user bit a bureaucratic institution)

    * if there is an error that really shouldn't happen, how will you notice? You probably don't have all the logs scrolling on 100 displays to watch for the red. So maybe send emails? But if you send emails about pointless stuff people will start to ignore them

  • scrame 2 days ago

    this completely happened to me, but with a comment:

    // this never happens

    ... guess what happened?

    /happenings

    • layer8 2 days ago

      In every project I have an unchecked CantPossiblyHappenException type (usually with a better name ;)) that is thrown in such cases. This documents that the developer thought this condition can’t occur, while still escalating it should it nevertheless occur.

anttiharju 2 days ago

Posted this because of the other Go error handling post today https://news.ycombinator.com/item?id=44171677

I like error wrapping. I've worked in codebases where systems had to be debugged by piecing together individual log lines. With error wrapping I can usually see the exact path that lead to the error in one line.

  • glenjamin 2 days ago

    It would be cool if someone could come up with a way for the runtime system to automatically wrap errors with the calling context.

    That way you’d be able to trace the stack of functions that were involved in passing an error back up to the place where it’s actually handled.

  • danesparza 2 days ago

    "With error wrapping I can usually see the exact path that lead to the error in one line"

    This is called a stack trace, and I agree it can be very useful (if the developers were thoughtful about their error handling)

    • eschatology 2 days ago

      Stack trace is much more verbose and shows the symbols leading to the failing function call The error wrapping(s) produce a log line containing a brief message from each layer in the codebase that expected no errors — subtle difference but one is a dump and the other is much more meaningful.

      • kubanczyk 2 days ago

        > The error wrapping(s) produce a log line containing a brief message from each layer in the codebase that expected no errors — subtle difference

        Agreed. How I articulate it, often a function is just another layer, does one core thing and one-two extras. I wrap meticulously the errors of the extras. The core errors mainly speak for themselves, so they rarely need any wrapping.

        Avoids:

            cannot load config:  cannot load config: cannot load config: file not found
        
        But promotes:

            cannot load config: cannot connect to Configurer: loading client cert: PEM invalid
        
        The latter case reads like a list of plot twists, because it is one. A corresponding 40-line stack trace might be less readable.
    • anttiharju 2 days ago

      I suppose I phrased this poorly. Stack traces are useful indeed. I guess what I like that usually wrapped errors are bit more thoughtful, stack traces can look a bit like "vomit".

      • RSHEPP 2 days ago

        from my experience of late, engineers usually toss stack traces into LLMs and ask what the issue is. good error wrapping, engineers grep for one of the first errors and get to the error code right away. both ways work.

        • sfn42 2 days ago

          If you can't read a stack trace without an LLM you're not an engineer.

          • danesparza 3 hours ago

            Counterpoint: You might also just be working on an exceptionally bad codebase or with an exceptionally bad runtime (I'm looking at you C/C++ or minified Javascript)

3cats-in-a-coat 2 days ago

"Handling errors gracefully" doesn't happen at the handler. It starts at the execution model and your architecture. If a component can "bomb" in an isolated way, then the client that invoked that component can handle that gracefully.

This means things like durability, consistency, atomicity, and isolated side-effects (if any).

This is what Erlang does. A process is isolated, so when it just falls apart, the parent can handle that "gracefully" despite said process literally disintegrated in a critical irreparable way.

It's a bit like designing covert spy networks...

Entwickler 2 days ago

Yeah, this has some general high level good advice, but is so old it doesn't include the new idiomatic ways of using errors.Is and error wrapping for error checking...

ninetyninenine 2 days ago

I love the go philosophy of errors being silent by default. It forces us developers to handle things gracefully. Additionally no stack traces along with the errors which is good because devs are too reliant on stack traces nowadays.

  • altruios 2 days ago

    This sounds like it needs an /s.

    The complaint of developers "being reliant on stack traces" tone sounds an awful lot like: "real programmers just use punch cards and ignore any tooling we've come up with in the last 70 years: just use your brain"

    • ninetyninenine 2 days ago

      It’s not sarcasm. This is just my personal philosophy. I feel attacked.

      • altruios a day ago

        I speak in hyperbole here. I only point out the giants whos shoulders we stand on left us fantastic tools to use.

        There is something to the philosophy of keeping your interface 'dark' such that you learn to 'shine'. But that's something I ascribe to a personal development journey.

datadrivenangel 2 days ago

Software should fall over quickly. Graceful error handling can hide many issues.

  • markwaldron 2 days ago

    My take on this post is that things will break, but they should tell you they broke in an actionable and somewhat standardized way. If the only message that shows up is "An error has occured" that doesn't help the user, especially if they are non-technical.

rollulus 2 days ago

This was a great article back then but Go’s errors package has changed since then quite a bit, with e.g. Is, As, and fmt.Errorf’s %w.

827a 2 days ago

For a language that prides itself on its error handling, that's a whole lot of words written on the myriad of incorrect and bad ways to handle errors in the language, many of which are actively and irreversibly deployed in the standard library.

carlio 2 days ago

"Something went wrong. Please try again".