• Badland9085@lemm.ee
    link
    fedilink
    arrow-up
    2
    ·
    4 hours ago

    It seems like the author thought stack traces are underrated because people don’t like exceptions and don’t always throw. It seems like they don’t understand why people don’t like exceptions, and think that stack traces should be there for every case where the author thinks should be an exception, and ties the desire to avoid exceptions to some strawman use case — a nice looking output — and called it “modern error handling”.

    Error / exception handling is separate from stack traces. You don’t need to have an exception to have a stack trace, and stack traces aren’t just used for exceptions.

    They also seem to not understand why people make do without stack traces in a microservice architecture. That’s simply not true. First off, you can still get stack traces of individual services. And secondly, if you build your services to accept, eg, something like a tracing ID, and print it along your logs, you essentially have a stack traces across services. In a web service, you can track the work done by all your systems for a single request from the client.

    Now, onto why exceptions are somewhat disliked. Let’s just get the simple stuff out of the way: they’re generally bad for performance; they’re invisible to the method caller until they run into the problem, meaning you can’t ever ship updates that you’re confident won’t fall over disgracefully; try-catch hell, etc.

    For a slightly more philosophical answer, why aren’t your exceptions just cases you need to handle? The try-catch pattern essentially builds up a separate channel of logic where your program needs to operate in but is expressed or recorded in very fragmented ways, forcing devs to have to pop open every function to look at why something is thrown, and hope that somewhere down the stack, no new exceptions are being thrown and not handled. The logic behind exceptions becomes second-class citizens that programmers can easily forget, instead of being front and centre. Can’t divide by 0? Tell me instead of setting me on a separate handling path. Why should I try-catch every single method call, or even property access? Don’t wait for the user to hit the call and just tell me that something is supposed to be impossible, or if I should handle the case where it doesn’t hold any values, right as I compile (dynamic languages can’t really do that).

    • Kissaki@programming.dev
      link
      fedilink
      English
      arrow-up
      4
      ·
      8 hours ago

      Maybe they’re under rated because the stack expands downwards the call chain? You could say they’re down under. /s

  • killeronthecorner@lemmy.world
    link
    fedilink
    English
    arrow-up
    4
    ·
    12 hours ago

    In go you can call, debug.Stack() at any time to get a stack trace. And it’s trivial to build error handling wrappers that can do this for on logging of an error.

    • atzanteol@sh.itjust.works
      link
      fedilink
      English
      arrow-up
      7
      arrow-down
      1
      ·
      10 hours ago

      You will get the stack at the point of your ‘debug.Stack()’ call though, not where the error happened.

      I’m leaning go, and starting to get used to it, but the error handling is just obnoxious. The constant “if err != nil” makes reading the actual logic so much harder. I’m surprised they haven’t come up with some syntactical sugar to make it simpler yet, but these devs seem to see it as some sort of “badge of honor” to suffer.

      • killeronthecorner@lemmy.world
        link
        fedilink
        English
        arrow-up
        2
        ·
        9 hours ago

        It will be where the error happened if you conventionally pass your errors to a logger that then prints the stack trace, which is virtually what Python et. al. are doing anyway.

        Go is not a language I’m a huge fan of tbh, but this mild inconvenience is not one of the things I would criticise it for. What you’re describing w.r.t control flow for errors absolutely is though.