-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
ref(angular) Add error-like objects handling #6446
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 |
---|---|---|
|
@@ -32,7 +32,7 @@ function tryToUnwrapZonejsError(error: unknown): unknown | Error { | |
|
||
function extractHttpModuleError(error: HttpErrorResponse): string | Error { | ||
// The `error` property of http exception can be either an `Error` object, which we can use directly... | ||
if (error.error instanceof Error) { | ||
if (isErrorOrErrorLikeObject(error.error)) { | ||
return error.error; | ||
} | ||
|
||
|
@@ -50,6 +50,35 @@ function extractHttpModuleError(error: HttpErrorResponse): string | Error { | |
return error.message; | ||
} | ||
|
||
function isObject(value: unknown): value is Record<string, unknown> { | ||
return value !== null && typeof value === 'object'; | ||
} | ||
|
||
function hasOwnProperty<ObjectType extends Record<string, unknown>, PropertyType extends PropertyKey>( | ||
object: ObjectType, | ||
propertyName: PropertyType, | ||
): object is ObjectType & Record<PropertyType, unknown> { | ||
return Object.prototype.hasOwnProperty.call(object, propertyName); | ||
} | ||
|
||
function hasErrorName(value: Record<string, unknown>): value is Pick<Error, 'name'> { | ||
return hasOwnProperty(value, 'name') && typeof value.name === 'string'; | ||
} | ||
|
||
function hasErrorMessage(value: Record<string, unknown>): value is Pick<Error, 'message'> { | ||
return hasOwnProperty(value, 'message') && typeof value.message === 'string'; | ||
} | ||
|
||
function hasErrorStack(value: Record<string, unknown>): value is Pick<Error, 'stack'> { | ||
return !hasOwnProperty(value, 'stack') || typeof value.stack === 'string'; | ||
} | ||
|
||
function isErrorOrErrorLikeObject(value: unknown): value is Error { | ||
return ( | ||
value instanceof Error || (isObject(value) && hasErrorName(value) && hasErrorMessage(value) && hasErrorStack(value)) | ||
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. of course this could all be inlined, but I find a lot more readable that way 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. It's very readable but we also have to consider the bundle size impact here. Hence my question if Maybe, we could also inline the 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. I'm not very familiar with how the code impacts the bundle size, is there a way I could check the result so that I can check different things to see if there is still a way to keep it readable without increasing the size too much? |
||
); | ||
} | ||
|
||
/** | ||
* Implementation of Angular's ErrorHandler provider that can be used as a drop-in replacement for the stock one. | ||
*/ | ||
|
@@ -117,16 +146,16 @@ class SentryErrorHandler implements AngularErrorHandler { | |
protected _defaultExtractor(errorCandidate: unknown): unknown { | ||
const error = tryToUnwrapZonejsError(errorCandidate); | ||
|
||
// We can handle messages and Error objects directly. | ||
if (typeof error === 'string' || error instanceof Error) { | ||
return error; | ||
} | ||
|
||
// If it's http module error, extract as much information from it as we can. | ||
if (error instanceof HttpErrorResponse) { | ||
return extractHttpModuleError(error); | ||
} | ||
|
||
// We can handle messages and Error objects directly. | ||
if (typeof error === 'string' || isErrorOrErrorLikeObject(error)) { | ||
return error; | ||
} | ||
|
||
// Nothing was extracted, fallback to default error message. | ||
return null; | ||
} | ||
|
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.
Not saying it's wrong but why do we need the
hasOwnProperty
check here? Wouldn't it be enough to check fortypeof value.name === 'string'
?Or actually, for the string check, we could simply reuse our
isString
check from@sentry/utils
.