0

I'm using Serverless to create Python AWS Lambda functions triggered by httpApi events.

My function (yes, I'm just passing back the context passed in by API Gateway so I can look at it):

def get_context(event, context):
try:
    typ = str(type(context))
    body = {
        "context_type": typ,
        "context": context
    }
    return {"statusCode": 200, "body": json.dumps(body)}
except Exception as e:
    estr = f"other python error: {e}"
    logger.error(estr) # AWS CloudWatch
    body = {"message": "FAIL", "error": estr}
    return {"statusCode": 500, "body": body}

I know the error in the try block is that the context object isn't serializable (thanks to the AWS Console).

But this question is about how the Exception block isn't making it to what Axios shows me client-side.

When I test it in the AWS Console, I get what I'd expect: Screenshot AWS Console shows my message

But when I use Axios, all I get is an Axios Error with error.response.status = 500 and error.response.data.message = "Internal Server Error".

I've spent hours searching stackoverflow, the serverless docs, etc. This pattern of returning a statusCode and a body works elsewhere. I can't figure out why I see my body in the AWS console and when I invoke via Serverless, but not in the Axios response. Any ideas? If it helps, I'm calling it in this function:

async apiPost(apiPath) {
  // apiPath = "/public/test/context"
  const apiName = "{resource defined in Amplify Configuration}";
  const myInit = {
    headers: {}, // OPTIONAL
    response: true, // OPTIONAL (return the entire Axios response object instead of only response.data)
  };
  try {
    const res = await API.post(apiName, apiPath, myInit); // aws-amplify API (Axios)
    this.api_res = JSON.stringify(res, null, 2);
    this.api_res_type = "Response";
  } catch (e) {
    this.api_res = axiosErrorHandler(e); // Just my attempts to dig through the error object...
    this.api_res_type = "ERROR";
  }
},

I've tried various combinations of json.dumps Python side, and iterating over the Axios properties clientside, trying to dig and see if it was getting buried somewhere on the Axios object, etc.

What I'd expect is for the Axios response data to have the body I sent to it, instead of a generic error masking what's really going on.

For the curious, here's the handler function. It just proves my response text isn't in the response anywhere / isn't related to why it isn't:

function axiosErrorHandler(err) {
  let res = {};
  if (err.response) {
    // The request was made and the server responded with a status code
    // that falls out of the range of 2xx
    res["condition"] = "Server Responded";
    res["body"] = err.response.data;
    res["statusCode"] = err.response.status;
    res["headers"] = err.response.headers;
  } else if (err.request) {
    // The request was made but no response was received
    // `err.request` is an instance of XMLHttpRequest in the browser and an instance of
    // http.ClientRequest in node.js
    res["condition"] = "No Server Response";
    res["request"] = err.request;
  } else {
    // Something happened in setting up the request that triggered an Error
    res["condition"] = "Request Setup Error";
    res["message"] = err.message;
  }
  return JSON.stringify(res, null, 2);
}
Brian
  • 1
  • 2
  • I found a workaround. It looks like anything in the 2xx range will "work" in the sense that I can get it. So if I return 299, I can at least see what Lambda said. Of course the browser now thinks that's a success, so I have to do my own shenanigans client-side to treat a 299 code as an error. If anyone knows how to get it to work appropriately, I'd still appreciate it! – Brian Mar 10 '23 at 18:28
  • " this.api_res = crapErrorHandler(e)" if this code executes and doesn't do what you want, you should include that function definition or a minimal example – erik258 Mar 10 '23 at 18:34
  • Thanks. I'll add the version when it was called "axiosErrorHandler" before 1,000 rabbit trails, lol. It just digs through the Axios properties / isn't directly relevant – Brian Mar 10 '23 at 19:34
  • another thought for you: your browser developer tools will let you view the response from the Lambda endpoint as its seen by the browser. That can take the DOM end out of the equation so you can figure out whether this is coming out of API Gateway, or it's your Javascript – erik258 Mar 10 '23 at 19:36
  • 1
    @erik258: Thanks. Yeah, same deal there. status code 500, generic error message. Thanks for mentioning it though. I've been watching the console so long I didn't think through... it's not an Axios problem, it's API Gateway issue. hmmm – Brian Mar 10 '23 at 19:43
  • Yeah, I was thinking the same thing. It might be because you're returning content instead of an error? https://docs.aws.amazon.com/apigateway/latest/developerguide/handle-errors-in-lambda-integration.html that example they raise an error, idk if that would expose the body of the response or not. Might be something in your integration as well – erik258 Mar 10 '23 at 19:56

0 Answers0