* Performs a network request against the API and handles the result.
(method: HTTPMethod, path: string, body?: any)
| 192 | * Performs a network request against the API and handles the result. |
| 193 | */ |
| 194 | private async makeRequest(method: HTTPMethod, path: string, body?: any): Promise<any> { |
| 195 | const token = await this.getToken() |
| 196 | const url = this.baseUrl + path |
| 197 | const serializedBody = body ? JSON.stringify(body) : undefined |
| 198 | |
| 199 | const result = await fetch(url, { |
| 200 | method: method, |
| 201 | body: serializedBody, |
| 202 | headers: { |
| 203 | Authorization: `Bearer ${token}`, |
| 204 | "Content-Type": "application/json" |
| 205 | } |
| 206 | }) |
| 207 | |
| 208 | switch (result.status) { |
| 209 | case 200: { |
| 210 | // Action endpoints such as Finish-Transaction and Set-App-Account-Token return 200 with an |
| 211 | // empty body, so we can't blindly call result.json() (it would throw on empty input). |
| 212 | const text = await result.text() |
| 213 | return text.length > 0 ? JSON.parse(text) : undefined |
| 214 | } |
| 215 | case 202: |
| 216 | return |
| 217 | |
| 218 | case 400: |
| 219 | case 403: |
| 220 | case 404: |
| 221 | case 429: |
| 222 | case 500: { |
| 223 | let retryAfter: number | undefined |
| 224 | const retryAfterHeader = result.headers.get("retry-after") |
| 225 | if (result.status === 429 && retryAfterHeader !== null) { |
| 226 | retryAfter = parseInt(retryAfterHeader) |
| 227 | } |
| 228 | throw await this.errorForResponse(result, retryAfter) |
| 229 | } |
| 230 | |
| 231 | case 401: |
| 232 | this.token = undefined |
| 233 | throw new Error("The request is unauthorized; the JSON Web Token (JWT) is invalid.") |
| 234 | |
| 235 | default: |
| 236 | throw new Error("An unknown error occurred") |
| 237 | } |
| 238 | } |
| 239 | |
| 240 | /** |
| 241 | * Builds an error from a non-success API response. |
no test coverage detected