DEV Community

Discussion on: How to handle errors in Go? [5 rules]

Collapse
 
asdftd profile image
Milebroke

But If logging is handling what should I return? Seems a bit confusing to me not returning an error but an (empty?) value? was this an error or should the value really be just empty?

Collapse
 
web3coach profile image
Lukas Lukac

Hm let me rephrase. You return an error and only log it if there is nothing else u can do with the error. So like on the example. I returned the error up the stack to the main.go bc it was the last place where I could handle it (log it) and then I exited the program.

Collapse
 
oscarhanzely profile image
OscarHanzely • Edited

This is kind of the biggest conundrum. If error happens in component or routine, we usually log the error there since log message can provide additional metadata that caused the problem or help to investigate potential bug. We don;t want to pass those parameters back to main routines to log them there. Its always better to handle/log the error where it occurs.

However after error happens and is logged inside the subrutine, we need to let know the main routine, API endpoint or place the component was called from that processing indeed failed. For that the best mechanism is return nil/default value and error (as even pointed out in this article). Is there other better mechanism to avoid this confusion, log error immediately with metadata/state that happened ?

Unfortunately the very simple example provided here to log in main routine is not always what is happening in more complicated systems with components/packages. I am trying to utilize both, the power of logging the error but also determining the behavior of main application/routine based on nil/err happened.

Thread Thread
 
web3coach profile image
Lukas Lukac

Very good, thought through question(s) Oscar.

I think you are asking 2 questions right?

1) Why do you think this is helpful? "Its always better to handle/log the error where it occurs."

IMHO, If you can handle an error, no need to log it, maybe as a warning. If you can't handle it, then you log it.

2) "Is there other better mechanism to avoid this confusion, log error immediately with metadata/state that happened ?"

I like to do this:

if nowNs % 2 > 0 {
        return "", TokenExpiredErr{expiredAt: nowNs}
    }

If I can't handle an error, I create a custom struct, decorated with all the information needed, and return it to the more competent component that can handle it (or can't and logs it).

Let me know if anything is unclear, or you have a concrete example. We can try to "debug it" together.