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

Bcfr 945 improve contract reader logs #14546

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from

Conversation

EasterTheBunny
Copy link
Contributor

@EasterTheBunny EasterTheBunny commented Sep 24, 2024

BCFR-945 improve logs and error handling for contract reader

All errors are structured as a ReadError with extra detail on the contract, method/event, parameters, etc. This data is now provided in the debug log.

@EasterTheBunny EasterTheBunny requested a review from a team as a code owner September 24, 2024 14:56
@EasterTheBunny EasterTheBunny requested review from krehermann and removed request for a team September 24, 2024 14:56
@@ -173,14 +173,26 @@ func (cr *chainReader) Unbind(ctx context.Context, bindings []commontypes.BoundC
func (cr *chainReader) GetLatestValue(ctx context.Context, readName string, confidenceLevel primitives.ConfidenceLevel, params any, returnVal any) error {
binding, address, err := cr.bindings.GetReader(readName)
if err != nil {
cr.lggr.Debug(err.Error())
Copy link
Contributor

@jmank88 jmank88 Sep 24, 2024

Choose a reason for hiding this comment

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

Is there more to say here?

Suggested change
cr.lggr.Debug(err.Error())
cr.lggr.Debugw("message","err",err)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Maybe this logging should be the responsibility of the caller. I did it here because this was the request as I understood it. My primary goal was to put more structured information in the errors themselves and ensure they are wrapped with the correct types for the loop interface.

return binding.GetLatestValue(ctx, common.HexToAddress(address), confidenceLevel, params, returnVal)
err = binding.GetLatestValue(ctx, common.HexToAddress(address), confidenceLevel, params, returnVal)
if err != nil {
cr.lggr.Debug(err.Error())
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not a fan of this pattern since it leads to double reporting of errors. What is the use case for logging the error that we are already returning? How will a node op know that this is not a distinct error from the one returned, if it ends up being logged as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree. Can we avoid logging here? @ilija42

Copy link
Contributor

Choose a reason for hiding this comment

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

Alternatively, we could generalize this a bit to be a GRPC "interceptor" that can cover every service, rather than just chain reader. This avoids the double error problem, because all of the interceptor logs come from the same place and the same logger name, so it is clear that this is a middleman and not the source or the handler of the error.

Copy link
Contributor

@ilija42 ilija42 left a comment

Choose a reason for hiding this comment

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

What do you think about wrapping errors with extra detail all the way up to the beginning of the stack, instead of logging them at the origin? So we would get something like this "failed to get latest value for xy at address xy ,err: failed to convert params xy to nativeOnchainTypes, err: failed to create codec type for item type xy"
Then, if it's a user input error, simply return it, but if it's an internal error, log it and return a generic internal error message. The goal is to make debugging this without opening up a debugger possible 😆

cc @jmank88 not sure how we usually do this

@EasterTheBunny
Copy link
Contributor Author

What do you think about wrapping errors with extra detail all the way up to the beginning of the stack, instead of logging them at the origin? So we would get something like this "failed to get latest value for xy at address xy ,err: failed to convert params xy to nativeOnchainTypes, err: failed to create codec type for item type xy" Then, if it's a user input error, simply return it, but if it's an internal error, log it and return a generic internal error message. The goal is to make debugging this without opening up a debugger possible 😆

cc @jmank88 not sure how we usually do this

That is why I tried adding a lot more information about each error to give better hints at where the error occurred in the call stack. Everything is a read error, but each error gets a bit more detail as it moves down the stack and also picks up input parameters as well. My main concern is security of printing some of the call parameters and return values to logs. That is what it is doing right now.

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.

3 participants