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

feat!: Use Error#cause in GaxiosError #661

Closed
wants to merge 12 commits into from

Conversation

danielbankhead
Copy link
Contributor

Modern runtimes offer Error#cause - a standard way of defining the cause of another error.

This will also improving logging in some environments that handle cause in a special way.

Documentation:

Migration Guide

Use the cause property rather than error.

old:

const rootError = new GaxiosError().error;

new:

const rootError = new GaxiosError().cause;

Background

Dependencies (merge this PR after):

Fixes #572 🦕

@danielbankhead danielbankhead requested a review from a team as a code owner October 26, 2024 00:00
@product-auto-label product-auto-label bot added the size: m Pull request size is medium. label Oct 26, 2024
Copy link

Warning: This pull request is touching the following templated files:

@danielbankhead danielbankhead added do not merge Indicates a pull request not ready for merge, due to either quality or timing. and removed do not merge Indicates a pull request not ready for merge, due to either quality or timing. labels Oct 28, 2024
@danielbankhead
Copy link
Contributor Author

Note: Should merge #660 first.

@danielbankhead danielbankhead added the next major: breaking change this is a change that we should wait to bundle into the next major version label Oct 29, 2024
@product-auto-label product-auto-label bot added size: s Pull request size is small. and removed size: m Pull request size is medium. labels Oct 30, 2024
@@ -99,9 +99,9 @@ export class GaxiosError<T = any> extends Error {
message: string,
public config: GaxiosOptionsPrepared,
public response?: GaxiosResponse<T>,
public error?: Error | NodeJS.ErrnoException,
cause?: unknown,
Copy link
Contributor

Choose a reason for hiding this comment

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

From the documentation, it seems like cause is in addition to, not instead of the error. Is it possible to set both in GaxiosError for it to not be a breaking change?

Also, seems like any is better than unknown here, WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As GaxiosError is an error itself (with a few additional custom params) it would enable a chain of Errors to be appropriately logged along with each individual call stacks - providing a complete context for customers. The error param was a stop-gap, but often it would not be used properly. I think cleanly migrating would be a more optimal UX instead of both.

unknown is the appropriate type - cause could be anything, but should be verified through type checks.

Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps a less destructive way then would be to add a deprecated tag to error, and simply continue to have it there? I'm concerned that it's a needlessly breaking change, especially since we're bundling a few other breaking changes in this release.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

A quick code search in googleapis will show virtually none of our libraries are using this property and it will be far more intuitive in the future to simply clean it up now.

Copy link
Contributor

Choose a reason for hiding this comment

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

Right but perhaps it's being used by external users?

if (e instanceof GaxiosError) {
err = e;
} else if (e instanceof Error) {
err = new GaxiosError(e.message, opts, undefined, e);
Copy link
Contributor

Choose a reason for hiding this comment

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

(just for my curiosity) - why wouldn't we contstruct the error with e.cause vs. e.message?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It allows GaxiosError to optionally have a root cause (say, the error is simple or purely on the gaxios level).

err.name === 'AbortError' ||
err.error?.name === 'AbortError'
(err.config.signal?.aborted && err.code !== 'TimeoutError') ||
err.code === 'AbortError'
Copy link
Contributor

Choose a reason for hiding this comment

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

why are we getting rid of err.name?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That line could never be true as err.name is always GaxiosError

Copy link
Contributor

Choose a reason for hiding this comment

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

Hm, this doesn't seem entirely relevant to this PR, I'm concerned it could have unintended consequences (even if it is a no-op). Would it be alright to leave it as a follow up?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It’s not relevant, but is a one-line change. Not at all a big deal. Not worthy of a separate PR.

Copy link
Contributor

Choose a reason for hiding this comment

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

Hm, those are often the most tricky! We've had this situation occur before. Until we have very robust integration testing, I think it would be wise to make small incremental changes. If we had good integration tests I'd feel better about it!

Copy link
Contributor

@sofisl sofisl left a comment

Choose a reason for hiding this comment

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

I think we should put the error in a deprecation tag, and remove the one-line change checking for the error name and put it in a separate PR (hopefully after the next major, if it really is not-breaking). There are too many breaking changes in this upcoming major as it is (6 and counting!) and it makes for a difficult migration for our downstream libraries and any external users.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
next major: breaking change this is a change that we should wait to bundle into the next major version size: s Pull request size is small.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

feat!: Use Native cause in GaxiosError
3 participants