Browse Source

chore(js): Fix parameter type in `handleXhrErrorResponse` (#49327)

The only time `handleXhrErrorResponse` is meant to be called (and indeed, the only time it _is_ called) is when handling a rejection from `Client.requestPromise` (either a direct call or though a helper function). Since we know that `requestPromise` always rejects with a `RequestError`, we can more accurately type the second parameter passed to `handleXhrErrorResponse`. This does that, and changes the parameter name to better reflect the type.
Katie Byers 1 year ago
parent
commit
af5d44abb5

+ 3 - 2
static/app/actionCreators/project.tsx

@@ -1,9 +1,10 @@
 import {addErrorMessage} from 'sentry/actionCreators/indicator';
-import {Client, ResponseMeta} from 'sentry/api';
+import {Client} from 'sentry/api';
 import {t} from 'sentry/locale';
 import ProjectsStore from 'sentry/stores/projectsStore';
 import {Project} from 'sentry/types';
 import {handleXhrErrorResponse} from 'sentry/utils/handleXhrErrorResponse';
+import RequestError from 'sentry/utils/requestError/requestError';
 
 /**
  * Fetches a project's details
@@ -19,7 +20,7 @@ export function fetchProjectDetails({
 }): Promise<Project> {
   const promise = api.requestPromise(`/projects/${orgSlug}/${projSlug}/`);
 
-  promise.then(ProjectsStore.onUpdateSuccess).catch((error: ResponseMeta) => {
+  promise.then(ProjectsStore.onUpdateSuccess).catch((error: RequestError) => {
     const message = t('Unable to fetch project details');
     handleXhrErrorResponse(message, error);
     addErrorMessage(message);

+ 4 - 3
static/app/actionCreators/savedSearches.tsx

@@ -1,7 +1,8 @@
-import {Client, ResponseMeta} from 'sentry/api';
+import {Client} from 'sentry/api';
 import {MAX_AUTOCOMPLETE_RECENT_SEARCHES} from 'sentry/constants';
 import {RecentSearch, SavedSearch, SavedSearchType} from 'sentry/types';
 import {handleXhrErrorResponse} from 'sentry/utils/handleXhrErrorResponse';
+import RequestError from 'sentry/utils/requestError/requestError';
 
 const getRecentSearchUrl = (orgSlug: string): string =>
   `/organizations/${orgSlug}/recent-searches/`;
@@ -29,7 +30,7 @@ export function saveRecentSearch(
     },
   });
 
-  promise.catch((err: ResponseMeta) =>
+  promise.catch((err: RequestError) =>
     handleXhrErrorResponse('Unable to save a recent search', err)
   );
 
@@ -61,7 +62,7 @@ export function fetchRecentSearches(
     },
   });
 
-  promise.catch((resp: ResponseMeta) => {
+  promise.catch((resp: RequestError) => {
     if (resp.status !== 401 && resp.status !== 403) {
       handleXhrErrorResponse('Unable to fetch recent searches', resp);
     }

+ 3 - 2
static/app/components/forms/controls/selectAsyncControl.tsx

@@ -3,9 +3,10 @@ import ReactSelect from 'react-select';
 import debounce from 'lodash/debounce';
 
 import {addErrorMessage} from 'sentry/actionCreators/indicator';
-import {Client, ResponseMeta} from 'sentry/api';
+import {Client} from 'sentry/api';
 import {t} from 'sentry/locale';
 import {handleXhrErrorResponse} from 'sentry/utils/handleXhrErrorResponse';
+import RequestError from 'sentry/utils/requestError/requestError';
 
 import SelectControl, {ControlProps, GeneralSelectValue} from './selectControl';
 
@@ -91,7 +92,7 @@ class SelectAsyncControl extends Component<SelectAsyncControlProps> {
         const {onResults} = this.props;
         return typeof onResults === 'function' ? onResults(resp) : resp;
       },
-      (err: ResponseMeta) => {
+      (err: RequestError) => {
         addErrorMessage(t('There was a problem with the request.'));
         handleXhrErrorResponse('SelectAsync failed', err);
         // eslint-disable-next-line no-console

+ 3 - 2
static/app/utils/customMeasurements/customMeasurementsProvider.tsx

@@ -2,13 +2,14 @@ import {useEffect, useState} from 'react';
 import {Query} from 'history';
 
 import {addErrorMessage} from 'sentry/actionCreators/indicator';
-import {Client, ResponseMeta} from 'sentry/api';
+import {Client} from 'sentry/api';
 import {getFieldTypeFromUnit} from 'sentry/components/events/eventCustomPerformanceMetrics';
 import {normalizeDateTimeParams} from 'sentry/components/organizations/pageFilters/parse';
 import {t} from 'sentry/locale';
 import {Organization, PageFilters} from 'sentry/types';
 import {CustomMeasurementCollection} from 'sentry/utils/customMeasurements/customMeasurements';
 import {handleXhrErrorResponse} from 'sentry/utils/handleXhrErrorResponse';
+import RequestError from 'sentry/utils/requestError/requestError';
 import useApi from 'sentry/utils/useApi';
 
 import {
@@ -83,7 +84,7 @@ export function CustomMeasurementsProvider({
 
           setState({customMeasurements: newCustomMeasurements});
         })
-        .catch((e: ResponseMeta) => {
+        .catch((e: RequestError) => {
           if (shouldCancelRequest) {
             return;
           }

+ 7 - 7
static/app/utils/handleXhrErrorResponse.tsx

@@ -1,21 +1,21 @@
 import * as Sentry from '@sentry/react';
 
-import {ResponseMeta} from 'sentry/api';
+import RequestError from 'sentry/utils/requestError/requestError';
 
-export function handleXhrErrorResponse(message: string, resp: ResponseMeta): void {
-  if (!resp) {
+export function handleXhrErrorResponse(message: string, err: RequestError): void {
+  if (!err) {
     return;
   }
-  if (!resp.responseJSON) {
+  if (!err.responseJSON) {
     return;
   }
 
-  const {responseJSON} = resp;
+  const {responseJSON} = err;
 
   // If this is a string then just capture it as error
   if (typeof responseJSON.detail === 'string') {
     Sentry.withScope(scope => {
-      scope.setExtra('status', resp.status);
+      scope.setExtra('status', err.status);
       scope.setExtra('detail', responseJSON.detail);
       Sentry.captureException(new Error(message));
     });
@@ -29,7 +29,7 @@ export function handleXhrErrorResponse(message: string, resp: ResponseMeta): voi
 
   if (responseJSON.detail && typeof responseJSON.detail.message === 'string') {
     Sentry.withScope(scope => {
-      scope.setExtra('status', resp.status);
+      scope.setExtra('status', err.status);
       scope.setExtra('detail', responseJSON.detail);
       scope.setExtra('code', responseJSON.detail.code);
       Sentry.captureException(new Error(message));

+ 3 - 2
static/app/utils/releases/releasesProvider.tsx

@@ -1,11 +1,12 @@
 import {createContext, useContext, useEffect, useState} from 'react';
 
 import {addErrorMessage} from 'sentry/actionCreators/indicator';
-import {Client, ResponseMeta} from 'sentry/api';
+import {Client} from 'sentry/api';
 import {normalizeDateTimeParams} from 'sentry/components/organizations/pageFilters/parse';
 import {t} from 'sentry/locale';
 import {Organization, PageFilters, Release} from 'sentry/types';
 import {handleXhrErrorResponse} from 'sentry/utils/handleXhrErrorResponse';
+import RequestError from 'sentry/utils/requestError/requestError';
 
 import useApi from '../useApi';
 
@@ -69,7 +70,7 @@ function ReleasesProvider({
         setLoading(false);
         setReleases(response);
       })
-      .catch((e: ResponseMeta) => {
+      .catch((e: RequestError) => {
         if (shouldCancelRequest) {
           setLoading(false);
           return;

+ 2 - 2
static/app/views/settings/projectGeneralSettings/index.tsx

@@ -7,7 +7,6 @@ import {
   removeProject,
   transferProject,
 } from 'sentry/actionCreators/projects';
-import {ResponseMeta} from 'sentry/api';
 import {hasEveryAccess} from 'sentry/components/acl/access';
 import {Button} from 'sentry/components/button';
 import Confirm from 'sentry/components/confirm';
@@ -26,6 +25,7 @@ import ProjectsStore from 'sentry/stores/projectsStore';
 import {Organization, Project} from 'sentry/types';
 import {handleXhrErrorResponse} from 'sentry/utils/handleXhrErrorResponse';
 import recreateRoute from 'sentry/utils/recreateRoute';
+import RequestError from 'sentry/utils/requestError/requestError';
 import routeTitleGen from 'sentry/utils/routeTitle';
 import withOrganization from 'sentry/utils/withOrganization';
 import AsyncView from 'sentry/views/asyncView';
@@ -94,7 +94,7 @@ class ProjectGeneralSettings extends AsyncView<Props, State> {
           // Need to hard reload because lots of components do not listen to Projects Store
           window.location.assign('/');
         },
-        (err: ResponseMeta) => handleXhrErrorResponse('Unable to remove project', err)
+        (err: RequestError) => handleXhrErrorResponse('Unable to remove project', err)
       );
   };