Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to capture errors when importing a module in Golang?

Tags:

import

go

In golang, when I import a module, its init() gets executed (before main() I assume?), it is possible some error is generated in this function. How can I capture these errors and handle them in my own code?

like image 300
NeoWang Avatar asked Dec 24 '22 18:12

NeoWang


2 Answers

Errors in Go are return values, as you may know. As init() does not return anything, the only alternative is to panic() in init if anything goes wrong.

A package that panics on init is arguably not very well designed, although there may be valid use cases for this.

Given the circumstances, recover() is not an option, because init is run before main. So if you can't edit the package in question, then you're out of luck.

This is one of the reasons why panic and recover should be used sparingly, only in situations where literally "panicking" makes sense.

@twotwotwo contributed the following quote from "effective Go" that describes this (for the init case):

if the library truly cannot set itself up, it might be reasonable to panic, so to speak

So: if your init function needs to report an error, then ask yourself if that code really belongs in init or would be better kept somewhere else. If it really has to be init, consider setting an error flag inside of the package and document that any client must check that error.

like image 98
thwd Avatar answered Jan 13 '23 14:01

thwd


Yes, package init() functions run before the main() function, see Package initialization in the language specification.

And no, you can't handle errors occurred in package init() functions. Even if you could, that would mean a package your program depends on failed to initialize and you wouldn't know what to expect from it.

Package init() functions have no return values and they can't panic in a meaningful way that was meant to recover from. If an init() function panics, the program terminates.

Since init() functions are not called by you (e.g. from the main() function), you can't recover from there. It is the responsibility of the package itself to handle errors during its initialization, not the users of the package.

One option to signal error happening during an init() is to store the error state in a variable (e.g. exported, or unexported but queryable by an exported function). But this should be used only if it is reasonable to continue, and this is also the task/responsibility of the package itself (to store/report the error) and not the users of the package. You can't do this without the cooperation of the package (you can't "catch" unhandled/unreported errors and panics).

like image 43
icza Avatar answered Jan 13 '23 13:01

icza