Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement transport level error handlers #863

Merged
merged 14 commits into from
Apr 24, 2019
Merged

Implement transport level error handlers #863

merged 14 commits into from
Apr 24, 2019

Conversation

sagikazarmark
Copy link
Contributor

@sagikazarmark sagikazarmark commented Apr 16, 2019

This is a first implementation for #861

I haven't provided any tests for now as the error loggers were not tested either, but I can write tests if necessary.

ToDo

  • Update examples once the implementation is settled

Copy link
Member

@peterbourgon peterbourgon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like it's on the right track.

// Usually this means logging the error.
type ErrorHandler interface {
Handle(err error)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You shouldn't need to define ErrorHandler in each individual transport package. Try defining it in the top-level transport package.

// ErrorHandler is a transport error handler implementation which logs an error.
type ErrorHandler struct {
logger Logger
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This belongs in package transport, not package log.

var output []interface{}

logger := log.Logger(log.LoggerFunc(func(keyvals ...interface{}) error {
output = keyvals
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably

output = append(output, keyvals...)

}

// ServerErrorHandler is used to handle non-terminal errors. By default, no errors
// are handled.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be a little bit less ambiguous to say e.g. "By default, non-terminal errors are ignored."

func ServerErrorLogger(logger log.Logger) ServerOption {
return func(s *Server) { s.logger = logger }
return func(s *Server) {
if s.errorHandler == nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the explicit check?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because the ErrorLogger should be considered deprecated and if someone uses an ErrorHandler, it should take precedence.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO ServerErrorLogger should now just be a helper function that calls e.g.

func ServerErrorLogger(logger log.Logger) ServerOption {
    return func(s *Server) { s.errorHandler = LoggingErrorHandler(logger) }
}

No need for precedence. You can keep the deprecation warning.

@sagikazarmark
Copy link
Contributor Author

Addressed all comments

Copy link
Member

@peterbourgon peterbourgon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple minor tweaks and this LGTM! Thank you very much, I think this is a great addition.

}

func (h *LogErrorHandler) Handle(err error) {
_ = h.logger.Log("err", err)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO no need for _ =

transport/error_handler.go Show resolved Hide resolved
@peterbourgon
Copy link
Member

If you rebase on master, the builds should be fixed.

@sagikazarmark
Copy link
Contributor Author

Thanks!

Rebased and applied the requested changes.

@sagikazarmark
Copy link
Contributor Author

Should I update the examples in this PR or in a separate one?

@peterbourgon
Copy link
Member

This one, if you don't mind.

@sagikazarmark
Copy link
Contributor Author

Not at all.

I'm wondering if we should somehow consider adding support for something like requested in #792
Maybe the error handler should accept a context as well? Or we should package the context into the error somehow and make it available through an interface?

@peterbourgon
Copy link
Member

Seems like a good idea. At first glance, if the errorHandler had a signature like func(context.Context, error), each transport could pass the context it already had, which would work, I think.

@sagikazarmark
Copy link
Contributor Author

I will add that as well then.

@sagikazarmark
Copy link
Contributor Author

Done and done.

@sagikazarmark
Copy link
Contributor Author

Anything else I can do here @peterbourgon ?

@peterbourgon peterbourgon merged commit 3c77e8c into go-kit:master Apr 24, 2019
@peterbourgon
Copy link
Member

Thanks, this is a great addition!

@sagikazarmark
Copy link
Contributor Author

Thanks!

@sagikazarmark sagikazarmark deleted the error-handler branch April 24, 2019 16:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants