I'm trying to do a mapping from AWS lambda function response using regex.
This is my regex:
.*statusCodeā:406.*
As you can see - I am trying for it to take a specific mapping from the following response:
{
"statusCode": 406,
"body": "{\"aerocrs\":{\"success\":false,\"error_type\":\"request\",\"details\":{\"detail\":\"Incorrect reqyest \",\"errorCode\":4}}}",
"headers": {
"x-powered-by": "Express",
"content-type": "application/json; charset=utf-8",
"content-length": "116",
"etag": "W/\"74-Zzo6HU1M1kKkLM9KGtX0jJdePQY\"",
"date": "Thu, 28 Nov 2019 16:03:05 GMT",
"connection": "close"
},
"isBase64Encoded": false
}
However, I always get to the default mapping.
When I change the mapping to .*.*, it gets to the correct one, which makes sense, but for some reason this regex isn't working.
Do you have any idea?
Thanks!
I managed to find the issue!
Thanks to this great person.
Long story short. AWS Api Gateway is SUPER picky and annoying regarding the error regex. This means, that is looking for a specific structure. Something of this sort:
{
"errorType": "string",
"errorMessage": "{\"body\":{\"success\":false,\"error_type\":\"request\",\"details\":{\"errorCode\":4}}}",
"trace": []
}
So the .*.* does work because it is valid for everything, but even a single letter, like .*s.* is causing an issue.
What you need to fix is in your lambda function.
In my case - I was using nodeJS function, and aws-serverless-express.
The aws-serverless-express is super easy as it works perfectly with express. However, I was using:
awsServerlessExpress.proxy(server, event, context);
Which was enough to return the response ok, but not enough to work with the API gateway's annoying regex.
Instead, I changed it to this:
awsServerlessExpress.proxy(server, event, context, 'CALLBACK', function(param1, response){
if (response.statusCode == 200) {
//Success
context.done(response.body);
}
else {
//Fail
context.fail(response.body);
}
});
And it worked like a charm. Now I took the response body and return it as success / fail. Then it will work with the format that the lambda function knows how to use.
I hope this will help other people not waste 6 hours on this!
looks like the output has a space before 406. what happens if you add that space to your regex?
--Edited to add: I use this site all the time (with redacted stuff, naturally) - https://regex101.com/
Related
I am moving away from scheduled task collection in azure to logic apps.
I'm trying to do a SIMPLE logic app that calls a URL every 2 minutes
When it runs, it is receiving this error:
Bad Request - Invalid Hostname
Add a ReOccurrence -> this works fine, it is running every 2 minutes.
Add HTTP Action
Set Method: Get
Set URI: My url to run
Set Headers: one header called VIA_METHOD
Queries is EMPTY
BODY is EMPTY
Set Authentication is NONE
Save and run and his is the error I get:
{
"statusCode": 400,
"headers": {
"Connection": "close",
"Date": "Fri, 20 Sep 2019 02:42:07 GMT",
"Server": "Microsoft-HTTPAPI/2.0",
"Content-Length": "334",
"Content-Type": "text/html; charset=us-ascii"
},
"body": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\"http://www.w3.org/TR/html4/strict.dtd\">\r\n<HTML><HEAD><TITLE>Bad Request</TITLE>\r\n<META HTTP-EQUIV=\"Content-Type\" Content=\"text/html; charset=us-ascii\"></HEAD>\r\n<BODY><h2>Bad Request - Invalid Hostname</h2>\r\n<hr><p>HTTP Error 400. The request hostname is invalid.</p>\r\n</BODY></HTML>\r\n"
}
Anyone know what it is failing? If I run the URL manually, it works fine.
I ended up deleting the "header" and re-adding it. I'm wondering if there was some escape characters int the response for the header when I copied it over.
I was getting the same "Invalid Host" error. In my case, I had a JWT token being used as the Authorization header. I had an extra CR/LF at the end of the token. I removed that extra CR/LF and the error no longer occurs.
I've been playing around with some web scraping but I've run into an issue I can't figure out; Using a nodejs server (on my local computer) I cannot get passed a permission error barring me from accessing the data. What is confusing to me most is that using the chrome extension "Postman" I don't run into the permission errors, but using the code generated by postman, I do (as well as fiddling with variations of my own scratch code).
Do I have to be using a live server? Do I need to include some extra items in the headers that aren't being put there by Postman? Is there some layer of security around the API that for some reason Postman has access do that a local machine doesnt?
Any light that can be shed would be of use. Note that there is no public documentation of the SmithsFoodAndDrug API (that I can find), so there aren't necessarily APIKeys that are going to be used. But the fact that Postman can access the information makes me think I should be able to on a node server without any special authentication set up.
In Summary:
I'm looking at SmithsFoodAndDrug product information, and found the API where they are grabbing information from.
I figured out the headers needed in order to get local price information on products (on top of the json body format for the POST request)
Using postman I can generate the POST request and retrieve the desired API results
Using nodejs (and the code generated by postman to replicate the request) with both 'request' module and standard 'http' module request module I receive permission errors from the server.
Details: (assume gathering data on honeycrisp apples (0000000003283) with division-id of 706 and store-id of 00144)
http://www.smithsfoodanddrug.com/products/api/products/details
Headers are 'division-id' and 'store-id'. Body is in format of {"upcs":["XXX"],"filterBadProducts":false} where XXX is the specific product code.
Here are the Request Headers in postman. Here are the Request Body settings in postman. The following is a portion of the json response (which is what I want).
{"products": [
{
"brandName": null,
"clickListItem": true,
"countryOfOrigin": "Check store for country of origin details",
"customerFacingSize": "price $2.49/lb",
...
"calculatedPromoPrice": "2.49",
"calculatedRegularPrice": "2.99",
"calculatedReferencePrice": null,
"displayTemplate": "YellowTag",
"division": "706",
"minimumAdvertisedPrice": null,
"orderBy": "Unit",
"regularNFor": "1",
"referenceNFor": "1",
"referencePrice": null,
"store": "00144",
"endDate": "2018-09-19T00:00:00",
"priceNormal": "2.55",
"priceSale": "2.12",
"promoDescription": "About $2.12 for each",
"promoType": null,
...
"upc": "0000000003283",
...
}
],
"coupons": {},
"departments": [],
"priceHasError": false,
"totalCount": 1 }
When using the code given by postman to replicate the request, I get the error saying 'You don't have permission to access "http://www.smithsfoodanddrug.com/products/api/products/details" on this server.
Reference #18.1f3de93f.1536955806.1989a2b1.' .
// Code given by postman
var request = require("request");
var options = { method: 'POST',
url: 'http://www.smithsfoodanddrug.com/products/api/products/details',
headers:
{ 'postman-token': 'ad9638c1-1ea5-1afc-925e-fe753b342f91',
'cache-control': 'no-cache',
'store-id': '00144',
'division-id': '706',
'content-type': 'application/json' },
body: { upcs: [ '0000000003283' ], filterBadProducts: false },
json: true };
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
change headers
headers:
{
'store-id': '00144',
'division-id': '706'
//'content-type': 'application/json'
}
I am receiving following error
{ error:
{ Error: Nock: No match for request {
"method": "GET",
"url": "http://localhost:3000/admin/orders/30075889/transactions.json",
"headers": {
"content-type": "application/json",
"host": "localhost:3000"
}
} Got instead {
"method": "GET",
"url": "http://localhost:3000/admin/orders/30075889/transactions.json",
"headers": {
"content-type": "application/json",
"host": "localhost:3000"
}
}
The url is as expected, not sure what's wrong, any pointer?
Use .log(console.log) to see the exact error message.
EX :
nock('https://test.org/sample')
.persist()
.log(console.log)
.get('/test')
.query({})
.reply(200, response);
When you use this and run the test, you will see something like this in the console
matching https://test.org/sample/test to GET https://test.org/sample/test with query({}): **true/false**.
If it says true, your request should be good. But if it says false, check both the requests and make sure they match.
Nock interceptors don't persist by default. For every request nock needs an interceptor. It looks like you only setup interceptor once and expect it to work for every request. If you want your interceptors to persist use .persist() option something like below.
var scope = nock('http://localhost.com')
.persist()
.get(/.*/)
.reply(200, 'Nock all get requests!');
you can display at any time prepared nocks, it's almost always a typo... ;)
console.log(nock.activeMocks());
(debuger in webstorm sucks and nock is undefined)
sometimes can be a encodedQueryParams: true option the problem
encoding query params is default behaviour these days, works well without such an option
I'm working with the spotify web api to build a Node.js app. One of the functions provided by the api allows you to play a specific track/album/playlist through the spotify player, here's the Start/Resume a User's Playback documentation.
However, when I send the put request, the song I chose doesn't start, it only continues playing the current song. I was hoping that it was my bad formatting of the json string to send, and not spotify's api not working?
Here's my code:
request({
method: 'PUT',
uri: 'https://api.spotify.com/v1/me/player/play',
headers:{
Authorization: 'Bearer ' + access_token
},
data:{
"context_uri": "spotify:user:spotify:playlist:37i9dQZF1DX0s5kDXi1oC5",
"offset": {
"position": 0
}
},
json: true
}, function (error, response, body) {
err = error;
});
I don't get any errors, as the api is doing it's job, I guess it just doesn't get the "context_uri" that I'm trying to give to it. I've also tried multiple different links for the context_uri that are valid.
So if you've looked at the documentation, I guess my question is should the context_uri be inside the "data" array, is that why it's not being seen?
Really appreciate the help, been trying to figure this out for days.
To confirm:
'context_uri': 'spotify:user:spotify:playlist:37i9dQZF1DX0s5kDXi1oC5',
'offset': {
'position': 0
}
works as expected for me. It begins playing Justin Timberlake - My Love.
So the problem is elsewhere. Things to consider:
The 'active' device hasn't recently been active / playing?
You're not catching an exception somewhere else?
So I'm writing a very simple POST request. When I try it in postman this work fine and i'm using the same parameters and url and headers.
The server tells me that parameters are missing. But I put the same input than in postman. So I guess i'm doing something wrong writing the options but I can't figure out what. Any idea ?
var options = {
method: 'POST',
url: self.rippledataapiProxyHost,
headers: {
"Content-Type": "application/json",
"Accept": "application/json"
},
body:JSON.stringify(parameters)
};
request(options, callback);
It seems the parameters are not taken in consideration at all. When i send wrong parameters in postman I get an error "wrong param...".
But here even if I send wrong parameters I get the error "missing param..."
Thanks a lot.
Implementation is correct I'm just a dummy puting the wrong url !