Browse Source

feat(ui): Throw error on non-json api responses (#57634)

Scott Cooper 1 year ago
parent
commit
6c5aa19e3e
1 changed files with 15 additions and 3 deletions
  1. 15 3
      static/app/api.tsx

+ 15 - 3
static/app/api.tsx

@@ -488,18 +488,18 @@ export class Client {
     // GET requests may not have a body
     // GET requests may not have a body
     const body = method !== 'GET' ? data : undefined;
     const body = method !== 'GET' ? data : undefined;
 
 
-    const headers = new Headers(this.headers);
+    const requestHeaders = new Headers(this.headers);
 
 
     // Do not set the X-CSRFToken header when making a request outside of the
     // Do not set the X-CSRFToken header when making a request outside of the
     // current domain. Because we use subdomains we loosely compare origins
     // current domain. Because we use subdomains we loosely compare origins
     if (!csrfSafeMethod(method) && isSimilarOrigin(fullUrl, window.location.origin)) {
     if (!csrfSafeMethod(method) && isSimilarOrigin(fullUrl, window.location.origin)) {
-      headers.set('X-CSRFToken', getCsrfToken());
+      requestHeaders.set('X-CSRFToken', getCsrfToken());
     }
     }
 
 
     const fetchRequest = fetch(fullUrl, {
     const fetchRequest = fetch(fullUrl, {
       method,
       method,
       body,
       body,
-      headers,
+      headers: requestHeaders,
       credentials: this.credentials,
       credentials: this.credentials,
       signal: aborter?.signal,
       signal: aborter?.signal,
     });
     });
@@ -535,6 +535,8 @@ export class Client {
 
 
           const responseContentType = response.headers.get('content-type');
           const responseContentType = response.headers.get('content-type');
           const isResponseJSON = responseContentType?.includes('json');
           const isResponseJSON = responseContentType?.includes('json');
+          const wasExpectingJson =
+            requestHeaders.get('Content-Type') === 'application/json';
 
 
           const isStatus3XX = status >= 300 && status < 400;
           const isStatus3XX = status >= 300 && status < 400;
           if (status !== 204 && !isStatus3XX) {
           if (status !== 204 && !isStatus3XX) {
@@ -550,6 +552,16 @@ export class Client {
                 // this should be an error.
                 // this should be an error.
                 ok = false;
                 ok = false;
                 errorReason = 'JSON parse error';
                 errorReason = 'JSON parse error';
+              } else if (
+                // Empty responses from POST 201 requests are valid
+                responseText?.length > 0 &&
+                wasExpectingJson &&
+                error instanceof SyntaxError
+              ) {
+                // Was expecting json but was returned something else. Possibly HTML.
+                // Ideally this would not be a 200, but we should reject the promise
+                ok = false;
+                errorReason = 'JSON parse error. Possibly returned HTML';
               }
               }
             }
             }
           }
           }