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
Related
I've been using reqwest for a few months now; solid features, reuse of types defined in http (and the like) and documentation.
I have the following http post request that works in Postman and curl that for reasons I can't figure out, generates a http::StatusCode "400 Bad Request".
Staring at and comparing the debug output of the request (below) over the past couple of days hasn't helped (ok, and a solid amount of reading the docs and playing with code too :)); thus the post.
The request spec that works with other clients
POST /2/files/list_folder HTTP/1.1
Host: api.dropboxapi.com
Authorization: Bearer <secret>
Content-Type: application/json
Content-Length: 65
{
"path": "",
"include_non_downloadable_files": false
}
The failing reqwest request code
let client = reqwest::Client::new();
let request = client
.request(
http::Method::from_str(method).unwrap(),
format!(
"{host}{endpoint}{query}",
host = &drive_server,
endpoint = &endpoint,
query = &query_ls
),
)
.header(AUTHORIZATION, format!("Bearer {}", access_token.secret()))
.header(CONTENT_TYPE, "application/json") // redundant when setting body with .json
.header(ACCEPT, "application/json")
.version(Version::HTTP_11)
.json(&req_body);
... and the code that builds the req_body:
// dropbox WIP
let json = r#"
{
"path": "",
"include_non_downloadable_files": false
}
"#;
#[derive(Deserialize, Serialize)]
struct ReqBody {
path: String,
include_non_downloadable_files: bool,
}
let req_body = serde_json::from_str::<ReqBody>(json)
.map_err(|err| AuthError::JsonParsingError(err.into()))?;
Debug output of the request
RequestBuilder {
method: POST,
url: Url {
scheme: "https",
cannot_be_a_base: false,
username: "",
password: None,
host: Some(
Domain(
"api.dropboxapi.com",
),
),
port: None,
path: "/2/files/list_folder",
query: None,
fragment: None,
},
headers: {
"authorization": "Bearer <secret>",
"content-type": "application/json",
"accept": "application/json",
},
}
Aside but to know what to expect from the diagnostic: Is the output expected to exclude the request body when present? I have not found a way to echo the request body once "theoretically" set :))
A bit more context
Finally, a bit more background, the explicit call to the version is a failed attempt on my part to override google drive forcing a switch to http 2 when it sees a request body (a separate use of this client). I'll have to figure out another way that includes some sort of conditional call to .json(<body>) without violating ownership issues, when services like dropbox require the body but not google. When I disable the .json on the reqwest RequestBuilder for a service such as google, the request works as expected.
Plainly put, the question
How do I build the http post request described at the top of this post using reqwest?
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/
I want to send multiple files to Github repository via nodejs. Tried several approaches and end up using node-rest-client module. Tried below code send a sample file to repository called 'metadata'. But after post I am getting error message "Request forbidden by administrative rules. Please make sure your request has a User-Agent header"...please let me know if anyone faced this error before and get rid of it.
convertval = "somedata";
var dataObj = {
"message": "my commit message",
"committer": {
"name": "Scott Chacon",
"email": "ravindra.devagiri#gmail.com"
},
"content": "bXkgbmV3IGZpbGUgY29udGVudHM="
}
debugger;
var Client = require('node-rest-client').Client;
var client = new Client()
var args = {
data: dataObj,
headers: { 'Content-Type': 'application/json' },
};
client.post("https://api.github.com/repos/metadata/contents", args, function (data, response) {
console.log("file send: True : " + data);
});
According to the REST API:
All API requests MUST include a valid User-Agent header. Requests with
no User-Agent header will be rejected.
First of all, you need to define 'User-Agent' with value 'request' in your request header. Refer to this link.
Second, endpoint you are trying to call might require authentication. Generate a personal token from here, add that token in your request header, 'Authorization': 'token '.
If you're using Git extensively in your code, I suggest you to use this - Nodegit.
Edit:
I don't think sending multiple files in a single request is possible in 'Contents' endpoints group (link).
You can checkout Git Data API (as discussed here).
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'
}
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 !