Reputation: 1901
So I'm kinda wondering what the best practice is here.
I have an application with several subpackages, some require access to the logger I have in the main package, because i use a custom logger with colors and timestamps etc.
Is the only way of accomplishing this by injecting it like so? (Assuming Handler is in a subpackage called command)
type Handler struct {
logger logging.Logger
}
func NewHandler(logger logging.Logger) Handler {
return Handler{
logger: logger,
}
}
handler := command.NewHandler(logger)
This issue I have with this is that testing becomes annoying since I have to mock the logger for tests. I thought about just returning errors that should be logged and let the main package deal with them, but I'd like to run some function async like so
go handler.HandleMessage(msg)
So idk how to handle errors from asynchronous functions or if its even possible.
So is there a best practice to do what I want?
Upvotes: 0
Views: 815
Reputation: 572
A few thoughts on this:
On this last point you can use anonymous functions to add additional error handling at the calling site:
go func() {
err := handler.HandleMessage(msg)
// err handling / logging here
}()
If you can pass errors up meaningfully to the calling site that initiated the call then I prefer to do this every time. You do need to bear in mind that you are still running in a separate goroutine when you come back from HandleMessage().
Upvotes: 2