Skip to content
This repository was archived by the owner on Jul 16, 2020. It is now read-only.

Improve error reporting in controller#1017

Merged
rbradford merged 2 commits into
ciao-project:masterfrom
rbradford:error-reporting-improvements-2
Jan 18, 2017
Merged

Improve error reporting in controller#1017
rbradford merged 2 commits into
ciao-project:masterfrom
rbradford:error-reporting-improvements-2

Conversation

@rbradford

Copy link
Copy Markdown
Contributor

Where we are able to return an error, wrap the error so that there is some useful context available for debugging.

Where we are not able to return an error (or on paths with multiple potential errors) ensure that the errors that do occur are logged in a consistent manner.

Also modify the prototype of GetStorageAttachments not to return an error as it cannot do so.

@coveralls

coveralls commented Jan 16, 2017

Copy link
Copy Markdown

Coverage Status

Coverage increased (+0.002%) to 66.809% when pulling 2954d22 on rbradford:error-reporting-improvements-2 into db44985 on 01org:master.

@rbradford

Copy link
Copy Markdown
Contributor Author

@kaccardi to review

@tpepper tpepper left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I'm surprised our golang automation didn't flag this pattern of function declared to return error but was not really. Nice cleanup!

t, err := ds.getTenant(id)
if err != nil || t == nil {
glog.V(2).Info(err, " unable to get tenant: ", id)
return nil, err

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Is this one intentionally bare?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes intentionally base. As ds.getTenant() wraps and we can't add any useful context over that one.

ts, err := ds.getTenants()

if err != nil {
return nil, err

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Intentionally bare?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, as we have nothing useful to add over the message in ds.getTenants()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Ok makes sense. ds.getTenants() either does something that can't fail or calls ds.db.getTenants(), where the latter would do an errors.Wrap().

if err == nil {
err = errors.Wrapf(err, "error releasing IP for instance (%v)", i.ID)
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Are the conditional wraps here required? I understood from https://dave.cheney.net/2016/04/27/dont-just-check-errors-handle-them-gracefully examples that you could just wrap nil and the right thing happened.

And is keeping the glog useful? I understood the idiom with errors.Wrap() to be one where you no longer do that.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Good point. I checked the code and Wrap(nil, "My message") returns nil.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

In this case I want to continue to do further cleanups and not return an error immediately. So therefore i'm logging so that both potentially errors will be seen even if only the first one is returned.

Hence why I save the error result into tmpError and then update err with the one that will be actually returned.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I was thinking in this function you could unconditionally do a series of errors.Wrapf(err, "text") and you'd end up with the cumulative set of wrapped errors if multiple, or the single one if just one, or none if none, and then return which ever it is in the single err at the end.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think that would be weird as you normally do that for a call chain, not multiple errors in the same function.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The officially expected usage paradigm is unclear. But from reading the documentation and watching the video, I see the wrap function as adding information to a stack of events where the stack is multiple errors. Whether those are from one function or a series of functions doesn't seem different to me in the abstract.

if tmpErr := ds.db.addFrameStat(i); tmpErr != nil {
if err != nil {
err = errors.Wrapf(tmpErr, "error adding stats to database")
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Another one where I thought you could just wrap unconditionally.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Here I want to continue around the loop even if any one errors out. The code is not consistent on this but i'm simply trying to adhere to the previous behaviour as closely as possible. A later cleanup might decide it's fine to abort halfway through the loop.

There is a bug here though, it should say if err == nil not err != nil.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

And now fixed.

Where we are able to return an error, wrap the error so that there is
some useful context available for debugging.

Where we are not able to return an error (or on paths with multiple
potential errors) ensure that the errors that do occur are consistently
logged.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
The prototype returns an error but there is no way for this code to
generate an error so modify the prototype and users not to generate an
error.

Fixes: ciao-project#1008

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
@rbradford rbradford force-pushed the error-reporting-improvements-2 branch from 2954d22 to 0bc450a Compare January 18, 2017 14:25
@coveralls

coveralls commented Jan 18, 2017

Copy link
Copy Markdown

Coverage Status

Coverage increased (+0.006%) to 66.795% when pulling 0bc450a on rbradford:error-reporting-improvements-2 into fe47dd3 on 01org:master.

@kaccardi kaccardi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM, thanks for the cleanup!

@rbradford rbradford merged commit dc1bc76 into ciao-project:master Jan 18, 2017
@rbradford rbradford deleted the error-reporting-improvements-2 branch February 21, 2017 15:41
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants