Repository navigation
refactor(core): remove unsafe type assertions in error utils (Phase 1.1) #19750
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
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -205,9 +205,13 @@ export function parseGoogleApiError(error: unknown): GoogleApiError | null { | |
| detailObj['@type'] = detailObj[typeKey]; | ||
| delete detailObj[typeKey]; | ||
| } | ||
| // We can just cast it; the consumer will have to switch on @type | ||
| // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion | ||
| details.push(detailObj as unknown as GoogleApiErrorDetail); | ||
| // Basic structural check before casting. | ||
| // Since the proto definitions are loose, we primarily rely on @type presence. | ||
| if (typeof detailObj['@type'] === 'string') { | ||
| // We can just cast it; the consumer will have to switch on @type | ||
| // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion | ||
| details.push(detailObj as unknown as GoogleApiErrorDetail); | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
@@ -223,6 +227,17 @@ export function parseGoogleApiError(error: unknown): GoogleApiError | null { | |
| return null; | ||
| } | ||
|
|
||
| function isErrorShape(obj: unknown): obj is ErrorShape { | ||
| return ( | ||
| typeof obj === 'object' && | ||
| obj !== null && | ||
| // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion | ||
| (('message' in obj && typeof (obj as ErrorShape).message === 'string') || | ||
| // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion | ||
| ('code' in obj && typeof (obj as ErrorShape).code === 'number')) | ||
| ); | ||
| } | ||
|
Comment on lines
+230
to
+238
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The type guard You can make this type guard safer by using a more constrained type for the cast, based on what has already been verified, which also allows removing the function isErrorShape(obj: unknown): obj is ErrorShape {
return (
typeof obj === 'object' &&
obj !== null &&
(('message' in obj &&
typeof (obj as { message: unknown }).message === 'string') ||
('code' in obj && typeof (obj as { code: unknown }).code === 'number'))
);
} |
||
|
|
||
| function fromGaxiosError(errorObj: object): ErrorShape | undefined { | ||
| const gaxiosError = errorObj as { | ||
| response?: { | ||
|
|
@@ -256,7 +271,10 @@ function fromGaxiosError(errorObj: object): ErrorShape | undefined { | |
| if (typeof data === 'object' && data !== null) { | ||
| if ('error' in data) { | ||
| // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion | ||
| outerError = (data as { error: ErrorShape }).error; | ||
| const potentialError = (data as { error: unknown }).error; | ||
| if (isErrorShape(potentialError)) { | ||
| outerError = potentialError; | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
@@ -313,7 +331,10 @@ function fromApiError(errorObj: object): ErrorShape | undefined { | |
| if (typeof data === 'object' && data !== null) { | ||
| if ('error' in data) { | ||
| // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion | ||
| outerError = (data as { error: ErrorShape }).error; | ||
| const potentialError = (data as { error: unknown }).error; | ||
| if (isErrorShape(potentialError)) { | ||
| outerError = potentialError; | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The type guard
isGaxiosErroris not safe becausetypeof nullis'object'. Iferror.responseisnull, this check will incorrectly pass. TheGaxiosErrorinterface expectsresponseto be an object with adataproperty orundefined, but notnull. Additionally, the type assertionas GaxiosErroris unsafe and can be avoided, which aligns with the goal of this PR.