API Gateway WebSocket handle errors - websocket

I'm setting a websocket app with API Gateway. I configured route responses for my lambda functions, so I'm able to handle these responses in my client side.
In my server, I return my response like this:
callback (null, {
statusCode: 500,
body: 'Some text.'
})
In my Websocket client side, the message event (onmessage) is triggered by this response.
The event.data contains the response body, due to lambda proxy integration response.
However, I can't find a way to trigger the error event (onerror), while my statusCode says that an error occured (500).
Do you have any solutions?

AWS Lambda function callbacks have the following structure: callback(error, result).
So for errors you would call it like callback(error) and for a successful result callback(null, result).
So what you shall be getting on your app is a success response (status code 200) which contains some data that has a field statusCode with value 500. So, as this is a successful response, it should not trigger onerror callback, but rather only onmessage.
My suggestion is that you handle status code response's other than 200 also inside your onmessage method and the onerror handler for errors other than the ones catch and retrieved from your lambda function (for example an AWS Api Gateway issue, a network issue, etc).

Related

Monitor network request URL and response content (Throw custom exceptions)

How can network requests be monitored and evaluated for their request URL, parameters, request, and response data?
Desired solution
I want to be notified or being given a custom exception, if specific content occurs in request or response.
Example
Assume a web application with many dynamic Ajax requests. A request or response might contain a broken value, e.g. undefined.
Request URL:
http://localhost:8080/app/?undefined=1
Response JSON data:
{"undefined":"1"}
Attempts
Filtering for request content in Dev Tools is not possible
PostMan tests seem not viable (e.g. no user interactions)
Not tried/found yet
Guesses of what might work ...
Software to intercepts requests and log/alert details
Proxying any URLs on an OS via some standalone application
If importing axios, you could leverage custom interceptors:
// Add a response interceptor
axios.interceptors.response.use(function (response) {
// Any status code that lie within the range of 2xx cause this function to trigger
// Do something with response data
return response;
}, function (error) {
// Any status codes that falls outside the range of 2xx cause this function to trigger
// Do something with response error
return Promise.reject(error);
});
// Similar functionality can be achieved for request
axios.interceptors.request.use(function (config) {
// Do something before request is sent
return config;
}, function (error) {
// Do something with request error
return Promise.reject(error);
});
Proxy software
For this case, any proxy that comes with logging ability, or can be extended:
https://mitmproxy.org
https://github.com/http-party/node-http-proxy
Exemplary for many variants under NodeJS
Tunneling
Expose localhost to a domain for testing:
https://ngrok.com
Use the logging capability to get request details:
https://ngrok.com/docs/ngrok-agent/api#list-requests
Localhost vs. 127.0.0.1
localhost should better become 127.0.0.1 or a custom dev domain. On MacOS, localhost did not work with HTTP interceptor browser plugins.

Invoking AWS Lambda Authorizer using Function URL

I have implemented an AWS Lambda Authorizer in Java (type=REQUEST). I would like to invoke the lambda using a Function URL. I need to pass the following fields to my Lambda AuthorizerEvent:
headers
type (REQUEST)
methodArn
I am sending the HTTP GET message using Postman. The headers get mapped correctly to the event object. However, type and methodARN are shown as null in the CloudWatch logs and the Function URL returns a 502 Bad Gateway error:
Received AuthorizerEvent(type=null, authorizationToken=null, headers={...}, methodArn=null)
I've tried putting type and methodArn in query parameters, headers and body (even though REQUEST authorizers don't use the body, see here). I also can't find complete documentation outlining how HTTP parameters are mapped to the lambda request event parameters for Authorizer Function URLs.
Any help would be greatly appreciated!

Azure Logic App - Get Response Body with 500 Internal Server Error

Is there any way to get the response body in Azure Logic App even when we get 500 Internal Server Error?
I have made the Logic App in a way that I'm setting the response code to 500 on an issue, and I'm adding some error related information in the response body. I tried returning 504 Gateway timeout as well, in case of a timeout issue I could face, but I'm always receiving a null response body in case of non-200 response codes.
If we are not able to see the response body in case of an error by design, is there a better way to set and fetch error related information from the response object?
Yes you can get the response body in Azure Logic App by adding the response action. According to this Add a Response action section of the Microsoft document.
When you use the Request trigger to handle inbound requests, you can model the response and send the payload results back to the caller by using the built-in Response action.
Following steps would help you to get the response body.
In the Logic App Designer, under the step where you want to add a Response action, select New step.
The under Choose an action, in the search box, enter response as your filter, and select the Response action.
Now add any values that are required for the response message. For the Body, you can select the trigger body output from the dynamic content list.
I would suggest to read the Receive and respond to inbound HTTPS requests in Azure Logic Apps document for more information.
Alternatively you can also create alerts whenever HTTP 500 errors occur in your App and use Application Insights to view it using Azure Monitor. I would also suggest to read this Handle errors and exceptions in Azure Logic Apps Microsoft document for more information.

Serverless WebSocket route responses

I am using serverless to create a WebSocket service, for which I am able to successfully trigger my WebSocket routes locally, using serverless-offline and for the deployed service.
The issue I am having now is responding to those WS events.
I am able to use AWS.ApiGatewayManagementApi.postToConnection to respond to my local WebSocket events, though I cannot seem to get the return value of my handler to actually send a WebSocket event in response, as these serverless-offline docs and these AWS docs suggest.
The serverless.yml route:
ws-custom:
handler: handler.wsCustom
events:
- websocket:
route: custom
routeResponseSelectionExpression: $default
The handler:
module.exports.wsCustom = async (event) => {
const body = JSON.parse(event.body);
console.log('WebSocket `custom` event!', event);
return {
statusCode: 200,
body: JSON.stringify({ message: `Hello, ${body.name}!` }),
};
}
Invoking the function in my browser JavaScript:
ws.send(JSON.stringify({ 'action': 'custom', 'name': 'kevbot' }));
The result is that my serverless-offline logs (or CloudWatch in the case of the deployed project) will create an event with the log successfully, but my client will receive no events in response.
Does anyone know how I can do this with the return value of the handler?
EDIT:
The problem seems to exist within my serverless-offline setup. I will attempt to get it working locally and will create an issue necessary.
An important point to note when using WebSocket APIs and trying to return a response from your integration back to the client, as mentioned in this doc:
For a route that is configured to use AWS_PROXY or LAMBDA_PROXY integration, communication is one-way, and API Gateway will not pass the backend response through to the route response automatically. For example, in the case of LAMBDA_PROXY integration, the body that the Lambda function returns will not be returned to the client. If you want the client to receive integration responses, you must define a route response to make two-way communication possible.
So, if you are using a proxy integration, then you cannot return a response back to the client. You would have to use the AWS.ApiGatewayManagementApi.postToConnection method to communicate any data.
Alternatively, if you are using a non-proxy integration, then you can set up a route response for your integration.

server response ajax request angular

first Ill comment my config in server
i have a apache with my html page with angular in 80 port
and other web server in port 4000 listening like a API
i am trying to make a $http request to my server but don't succes, just error message, this is my code
$http.post('http://localhost:4000/tareas', {msg:'asd'}).
success(function(data, status) {
alert('funciono');
}).
error(function(data, status) {
alert('error');
});
my server receive that request because i send a message when a controller is accesed, so the request connect with my API, but always execute the error my request in angular, even with $http.jsonp, that send me the error alert, my server return a simple json.
{data:'hurra.!', status:200}
i need a different response from my server to success?
even with F12 and neetwork, i see the request "canceled" with get and post, but my server send the message so i receive that request. with jsonp, chromium don't say a thin, everything is ok, but the $http.json still send me to error, is because my server response?
thanks to all.
well, searching more i find that cross domain request need "callback=JSON_CALLBACK" in the url and do a jsonp request, so changing my code to
$http.jsonp('http://localhost:4000/tareas?callback=JSON_CALLBACK'}).
success(function(data, status) {
alert('funciono');
}).
error(function(data, status) {
alert('error');
});
do the work and my ajax request now success... i find this in other tread, i put here the link for more info.
parsing JSONP $http.jsonp() response in angular.js
thanks

Resources