diff --git a/static/app/api.tsx b/static/app/api.tsx index 09a17106099a8a..02bcfe535f78b3 100644 --- a/static/app/api.tsx +++ b/static/app/api.tsx @@ -551,7 +551,7 @@ export class Client { // This *should* get logged to Sentry only if the promise rejection is not handled // (since SDK captures unhandled rejections). Ideally we explicitly ignore rejection // or handle with a user friendly error message - const preservedError = new Error(); + const preservedError = new Error('API Request Error'); return new Promise((resolve, reject) => this.request(path, { @@ -567,11 +567,10 @@ export class Client { error: (resp: ResponseMeta) => { const errorObjectToUse = createRequestError( resp, - preservedError.stack, + preservedError, options.method, path ); - errorObjectToUse.removeFrames(2); // Although `this.request` logs all error responses, this error object can // potentially be logged by Sentry's unhandled rejection handler diff --git a/static/app/utils/requestError/createRequestError.tsx b/static/app/utils/requestError/createRequestError.tsx index 984f7e1afdeee9..06b162a21fa0b1 100644 --- a/static/app/utils/requestError/createRequestError.tsx +++ b/static/app/utils/requestError/createRequestError.tsx @@ -25,11 +25,11 @@ const ERROR_MAP = { */ export default function createRequestError( resp: ResponseMeta, - stack: string | undefined, + cause: Error, method: 'POST' | 'GET' | 'DELETE' | 'PUT' | undefined, path: string ) { - const err = new RequestError(method, path); + const err = new RequestError(method, path, {cause}); if (resp) { const errorName = ERROR_MAP[resp.status]; @@ -41,9 +41,5 @@ export default function createRequestError( err.setResponse(resp); } - if (stack) { - err.setStack(stack); - } - return err; } diff --git a/static/app/utils/requestError/requestError.tsx b/static/app/utils/requestError/requestError.tsx index 4fb99a9c50a736..5411f516f6f26f 100644 --- a/static/app/utils/requestError/requestError.tsx +++ b/static/app/utils/requestError/requestError.tsx @@ -2,14 +2,17 @@ import {ResponseMeta} from 'sentry/api'; import {sanitizePath} from './sanitizePath'; +interface ErrorOptionsObject { + cause: Error; +} export default class RequestError extends Error { responseText?: string; responseJSON?: any; status?: number; statusText?: string; - constructor(method: string | undefined, path: string) { - super(`${method || 'GET'} ${sanitizePath(path)}`); + constructor(method: string | undefined, path: string, options: ErrorOptionsObject) { + super(`${method || 'GET'} "${sanitizePath(path)}"`, options); this.name = 'RequestError'; Object.setPrototypeOf(this, new.target.prototype); } @@ -41,25 +44,7 @@ export default class RequestError extends Error { this.message = message; } - setStack(newStack: string) { - this.stack = newStack; - } - setName(name: string) { this.name = name; } - - removeFrames(numLinesToRemove) { - // Drop some frames so stack trace starts at callsite - // - // Note that babel will add a call to support extending Error object - - // Old browsers may not have stack trace - if (!this.stack) { - return; - } - - const lines = this.stack.split('\n'); - this.stack = [lines[0], ...lines.slice(numLinesToRemove)].join('\n'); - } }