I'm building an app that connects with a serverless API on AWS (API Gateway/Lambda) via AWS Amplify used on a web (React) frontend.
When the request is successful, everything works just fine (definitionally, I suppose). There are no CORS issues or anything. But if I try to return a "failed" response, my frontend does not receive that response. It receives a generic Network Error with no information about what happened, and the console logs a failure.
I think the code will make more sense of this. I request to the API using code like this (Amplify configured elsewhere):
import { API } from 'aws-amplify';
...
API.get('apiName', path, options)
.then(response => {
// Whatever
})
.catch(err => {
// Whatever
})
In the Lambda, I'm returning (and Cloudwatch verifies this, as I log right before running callback(null, responseObject)) a full response object like this:
{
"statusCode": 200,
"headers": {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Credentials": true
},
"body": "{ /* whatever */ }"
}
or this:
{
"statusCode": 500,
"headers": {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Credentials": true
},
"body": "{ /* error here */ }"
}
In the 200 case, the response reaches my frontend perfectly (shows up in the .then function as response). In the 500 (or general error) case, the .catch is called and the err object is not what I put in the response body, but rather a generic Network Error with no relevant information (or status code):
Error: Network Error
at createError (createError.js:16)
at XMLHttpRequest.handleError (xhr.js:87)
To clarify, simply changing the statusCode from 200 to 400 both means the request is caught on the frontend (good), and that the error has none of the information I'm returning from the Lambda (bad).
The console also logs errors:
DELETE https://abcdefg.execute-api.us-west-2.amazonaws.com/development/my-endpoint 403 ()
Failed to load https://abcdefg.execute-api.us-west-2.amazonaws.com/development/my-endpoint: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 403.
It also logs stuff related to a CORS failure that makes no sense to me, because I'm following the exact same pattern as for success cases, just with a higher statusCode.
Cross-Origin Read Blocking (CORB) blocked cross-origin response https://abcdefg.execute-api.us-west-2.amazonaws.com/development/my-endpoint with MIME type application/json.
XHR failed loading: DELETE "https://abcdefg.execute-api.us-west-2.amazonaws.com/development/my-endpoint".
Any idea what's going on here? It's really frustrating not to have access to the real informative error on the frontend. Please let me know if there's any other information that would be helpful for solving this issue.
EDIT -- following @Michael's feedback below, I checked to see if my app was using lambda or lambda-proxy, and it is, in fact, using lambda-proxy, which should not produce this behavior, as I understand it.
Here's some code in my serverless.yml file,
functions:
projectsGetAll:
handler: handlers/projects/getAll.handler
events:
- http:
path: projects
method: get
cors: true
authorizer: aws_iam
And here's a screenshot (with the endpoint whited out) from AWS API Gateway for one of these endpoints:
I want to confirm that this is, then, unexpected behavior for lambda-proxy. Is there possibly some setting that is mucking things up?
