zerolog icon indicating copy to clipboard operation
zerolog copied to clipboard

Best way to propagate an error to the top without losing context?

Open anthops opened this issue 6 months ago • 0 comments

Hey all,

I'm relatively new to Go so forgive me if this is a stupid question.

I've been using zerolog and enjoy being able to add extra fields to the logs, e.g.:

log.Info().Str("foo", "bar").Int("number", 42).Msg("something happened")

Unfortunately, I'm stuck on error handling. Deep in my code I want to log errors wrapped with some context, just like above. However, from my experience in other languages as well as from what I've read about Go it's best to return the error and propagate it upwards until it is handled and consequently logged.

So for example:

func doThing(id string) error {
    logger := log.With().Str("id", id).Logger()
    logger.Info().Msg("Doing thing")
    if err := something(); err != nil {
        // avoid logging here to prevent duplication
        return fmt.Errorf("doThing failed: %w", err)
    }
    return nil
}

func main() {
    err := doThing("abc123")
    if err != nil {
        // want to log the error with the original id field here
        log.Error().Err(err).Msg("operation failed")
    }
}

This will give output like this:

{"level":"info","id":"abc123","message":"Doing thing"}
{"level":"error","error":"doThing failed: <some error>","message":"operation failed"}

I was wondering if anyone knew a good way to preserve the additional context I added so the output would look like:

{"level":"info","id":"abc123","message":"Doing thing"}
{"level":"error","id":"abc123","error":"doThing failed: <some error>","message":"operation failed"}

I know I could just log when the error occurs but that wouldn't be ideal.

Thank you :)

anthops avatar Jun 09 '25 14:06 anthops