aws-amplify / amplify-js

A declarative JavaScript library for application development using cloud services.
https://docs.amplify.aws/lib/q/platform/js
Apache License 2.0
9.42k stars 2.12k forks source link

API Gateway with rate limit makes API.get return arbitrary AXIOS error #12537

Closed mkilp closed 10 months ago

mkilp commented 10 months ago

Before opening, please confirm:

JavaScript Framework

React

Amplify APIs

REST API

Amplify Categories

api

Environment information

``` System: OS: Windows 10 10.0.19045 CPU: (16) x64 11th Gen Intel(R) Core(TM) i9-11950H @ 2.60GHz Memory: 17.51 GB / 39.73 GB Binaries: Node: 16.14.2 - C:\Program Files\nodejs\node.EXE Yarn: 1.22.19 - C:\Program Files (x86)\Yarn\bin\yarn.CMD npm: 8.12.1 - C:\Program Files\nodejs\npm.CMD Browsers: Edge: Spartan (44.19041.1266.0), Chromium (119.0.2151.44) Internet Explorer: 11.0.19041.1566 npmPackages: @emdgroup-liquid/liquid: ^1.12.1 => 1.12.1 @liquid-design/liquid-design-react: ^2.7.5 => 2.7.5 @reduxjs/toolkit: ^1.5.0 => 1.8.3 @reduxjs/toolkit-query: 1.0.0 @reduxjs/toolkit-query-react: 1.0.0 aws-amplify: ^5.3.12 => 5.3.12 axios: ^0.21.1 => 0.21.4 (1.6.0) connected-react-router: ^6.8.0 => 6.9.2 dotenv-cli: ^5.1.0 => 5.1.0 eslint: ^7.24.0 => 7.32.0 eslint-config-airbnb: ^18.2.1 => 18.2.1 eslint-plugin-import: ^2.22.1 => 2.26.0 eslint-plugin-jsx-a11y: ^6.4.1 => 6.6.0 eslint-plugin-react: ^7.23.2 => 7.30.1 eslint-plugin-react-hooks: ^4.2.0 => 4.6.0 history: ^4.7.2 => 4.10.1 liquid-loader: undefined () normalizr: ^3.6.1 => 3.6.2 prop-types: ^15.7.2 => 15.8.1 query-string: ^6.13.7 => 6.14.1 (4.3.4) react: ^17.0.2 => 17.0.2 (18.2.0) react-app-polyfill: ^1.0.6 => 1.0.6 (2.0.0) react-cookie: ^4.0.3 => 4.1.1 react-csv: ^2.0.3 => 2.2.2 react-dom: ^17.0.2 => 17.0.2 react-inner-image-zoom: ^3.0.1 => 3.0.1 react-redux: ^7.2.2 => 7.2.8 react-router-dom: ^5.2.0 => 5.3.3 react-scripts: 4.0.3 => 4.0.3 react-select: ^4.3.1 => 4.3.1 react-slick: ^0.29.0 => 0.29.0 react-zoom-pan-pinch: ^2.6.1 => 2.6.1 reduce-reducers: ^1.0.4 => 1.0.4 redux: ^4.0.5 => 4.2.0 redux-logger: ^3.0.6 => 3.0.6 redux-thunk: ^2.3.0 => 2.4.1 reselect: ^4.0.0 => 4.1.6 save-svg-as-png: ^1.4.17 => 1.4.17 slick-carousel: ^1.8.1 => 1.8.1 styled-components: ^5.2.1 => 5.3.5 styled-components/macro: undefined () styled-components/native: undefined () styled-components/primitives: undefined () victory: ^35.5.1 => 35.11.4 ```

Describe the bug

My API gateway is enabled with rate limiting and returns error code 429 (built in function) when the limit is hit. This causes the OPTIONS request to fail from amplify. This in turn then causes my browser to reject the request due to a cors error:

Access to XMLHttpRequest at 'https:/xxx/stage/me' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.

This then causes amplify-js to return a generic AXIOS network error instead of a proper one with http status and co:

[DEBUG] 34:56.825 RestClient AxiosError {message: 'Network Error', name: 'AxiosError', code: 'ERR_NETWORK', config: {…}, request: XMLHttpRequest, …}code: "ERR_NETWORK"config: {transitional: {…}, adapter: Array(2), transformRequest: Array(1), transformResponse: Array(1), timeout: 0, …}message: "Network Error"name: "AxiosError"request: XMLHttpRequest {onreadystatechange: null, readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, …}stack: "AxiosError: Network Error\n at XMLHttpRequest.handleError (http://localhost:3000/static/js/vendors~main.chunk.js:4891:14)"

I am not sure if its because chrome blocks the request or because the options request fails - but it is very frustrating.

I have added all cors headers to the options route: image image

I am not sure if I am missing some step to be able to detect a rate limited api call and display an error.

Expected behavior

amplify provides me a proper error with the error code.

Reproduction steps

Set up a blank amplify project and set the rate limits on a route to 0 for rate and burst.

Code Snippet

// Put your code below this line.

Log output

``` // Put your logs below this line [DEBUG] 34:56.825 RestClient AxiosError {message: 'Network Error', name: 'AxiosError', code: 'ERR_NETWORK', config: {…}, request: XMLHttpRequest, …}code: "ERR_NETWORK"config: {transitional: {…}, adapter: Array(2), transformRequest: Array(1), transformResponse: Array(1), timeout: 0, …}message: "Network Error"name: "AxiosError"request: XMLHttpRequest {onreadystatechange: null, readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, …}onabort: ƒ handleAbort()onerror: ƒ handleError()onload: nullonloadend: ƒ onloadend()onloadstart: nullonprogress: nullonreadystatechange: nullontimeout: ƒ handleTimeout()readyState: 4response: ""responseText: ""responseType: ""responseURL: ""responseXML: nullstatus: 0statusText: ""timeout: 0upload: XMLHttpRequestUpload {onloadstart: null, onprogress: null, onabort: null, onerror: null, onload: null, …}withCredentials: false[[Prototype]]: XMLHttpRequeststack: "AxiosError: Network Error\n at XMLHttpRequest.handleError (http://localhost:3000/static/js/vendors~main.chunk.js:4891:14)"[[Prototype]]: Error ```

aws-exports.js

No response

Manual configuration

No response

Additional configuration

No response

Mobile Device

No response

Mobile Operating System

No response

Mobile Browser

No response

Mobile Browser Version

No response

Additional information and screenshots

No response

elorzafe commented 10 months ago

@mkilp did you have the same problem with previous versions of the library or this is after updating to latest?

cwomack commented 10 months ago

Hello, @mkilp 👋. I believe the client-side library behaves as expected here based on the issue description. Due to CORS constraints, the client-side JavaScript code cannot access the details of a preflight request. When a preflight request fails, the JavaScript library only knows it's a networking error. It also aligns with the spec for fetch API.

For best practices to prevent the preflight requests from getting throttled, can you reach out to the API Gateway service team. I'm not sure if there's much on the Amplify side that can be done here.

mkilp commented 10 months ago

Hi @cwomack, thanks for the response!

I actually took your hint and manually excluded the OPTIONS route inside API gateway from throttling. However I am still facing the same issue weirdly enough. If I send a manual preflight OPTIONS call to my API route via Postman I get a normal 200 response. Chrome / amplify however returns 429 too many requests on the preflight request which causes the low level network error again. After I deployed my throttle exception it worked for a hot second before going back to not working again.

While using my webapp and post man at the same time I could see postman switching from 429 to 200 running the OPTIONS request while the webapp keeps getting 429. I'm honestly at a loss and also reached out to the api gateway team. However since the requests succeed in Postman I am not sure how they will be able to help.

@elorzafe I had the issue both with an old version and latest.

mkilp commented 10 months ago

Hi @cwomack I actually take it back, the follow up error was on my end with a wrong api url.

Manually overriding the throttle inside API gateway for the OPTIONS route solved the issue for me for anyone reading this.

Thanks for your help!