how to get the response api with status code is 400? - javascript

I consume api and when the api returns 200 status code, I return the response, but when the api returns 400 status code the api returns array with the errors, my questions is how can i get this array errors and return this array.
the code
try {
const config = {
method: 'get',
url: 'http://localhost:4000/api/orders',
headers: {'Key': '96db259b-2239-4abb-9b9d-a682a1de6b3c'}
}
const result = await axios(config)
return result.data
} catch (error) {
console.log('error ' + error)
returns result.data.errors
}
this the response whit the status code is 400.
"errors": [
{
"value": "96db259b-2239-4abb-9b9d-a682ssa1de6b3c",
"msg": "the API key 96db259b-2239-4abb-9b9d-a682ssa1de6b3c is invalid",
"param": "key",
"location": "headers"
}
]

You can do like this
try {
const config = {
method: 'get',
url: 'http://localhost:4000/api/orders',
headers: {'Key': '96db259b-2239-4abb-9b9d-a682a1de6b3c'}
}
const result = await axios(config)
if(result.status != 200) {
throw new Error(`[Status ${result.status}] Something went wrong `);
}
return result.data
} catch (error) {
console.log('error ' + error)
returns error.message;
}

Only do you need call the message attribute of error, for example:
try {
const config = {
method: 'get',
url: 'http://localhost:4000/api/orders',
headers: {'Key': '96db259b-2239-4abb-9b9d-a682a1de6b3c'}
}
const result = await axios(config)
return result.data // this only called with success response, status code 200
} catch (error) {
console.log('error ' + error)
returns error.message;
}

Related

NodeJS Fetch Not Waiting

I'm trying to force Node to wait for either a success or a failure. I understood fetch to return a promise and I thought I told it how to handle both.
The following code does not honor the await I asked it to do:
async function getAccessToken() {
...
let fetchResult = await fetch(argumentParserResult.authorizationUrl, {
method: 'POST',
body: formData,
headers: headers
}).then(success => {
console.log("Success reached. " + JSON.stringify(success));
process.exit(2);
}, other => {
console.log("Other reached. " + JSON.stringify(other));
process.exit(3);
});
console.log('## after fetch fetchResult=' + fetchResult);
...
}
You might think that the await would cause it to, wait for the Promise to complete, but instead it leaves the whole function, and goes back to the caller. It does not print the '## after fetch fetchResult=' line. Neither the failure, nor success handler is executed.
I should point out that it also does not appear to make the requested POST call either. Instead, it sees that request and does something completely different without raising any exception.
Why is it not honoring the 'await' keyword whatsoever?
--- If I try the try/catch approach as follows:
async function getAccessToken() {
console.log('##getAccessToken BP1');
if (argumentParserResult.authenticationScheme == 'OAUTH2') {
console.log('##getAccessToken BP2');
const fetch = require('node-fetch');
const url = argumentParserResult.resourceUrl;
console.log('##getAccessToken BP3');
let formData = new URLSearchParams({
'grant_type': 'client_credentials',
'client_id': argumentParserResult.clientId,
'scope': argumentParserResult.clientScope,
'client_secret': argumentParserResult.clientSecret
})
console.log('##getAccessToken BP4');
let headers = {
'Content-Type': 'application/x-www-form-urlencoded'
};
console.log('##getAccessToken BP5');
console.log('POST ' + argumentParserResult.authorizationUrl);
console.log(JSON.stringify(formData));
console.log('##getAccessToken BP6');
try {
console.log('##getAccessToken BP7');
const response = await fetch(argumentParserResult.authorizationUrl, {
method: 'POST',
body: formData,
headers,
});
console.log('##getAccessToken BP8');
console.log(`Success reached.`, JSON.stringify(response));
const json = await response.json();
console.log('##getAccessToken BP9');
console.log(`Other reached.`, json);
return json;
} catch (error) {
console.log('##getAccessToken BP10');
console.log(`!! something went wrong`, error.message);
console.error(error);
return error;
} finally {
console.log('##getAccessToken BP11');
console.log(`fetch finished`);
}
console.log('##getAccessToken BP12');
}
console.log('##getAccessToken BP13');
return "Should not have reached this point";
}
I get
##getAccessToken BP1
##getAccessToken BP2
##getAccessToken BP3
##getAccessToken BP4
##getAccessToken BP5
POST https://some-url
{}
##getAccessToken BP6
##getAccessToken BP7
As you can see, it goes just inside of the try block, then goes back to the caller without triggering the finally, error handlers or the logging after the fetch.
Using the .then approach as follows:
async function getAccessToken() {
console.log('##getAccessToken BP1');
if (argumentParserResult.authenticationScheme == 'OAUTH2') {
console.log('##getAccessToken BP2');
const fetch = require('node-fetch');
const url = argumentParserResult.resourceUrl;
console.log('##BP1.9');
let formData = new URLSearchParams({
'grant_type': 'client_credentials',
'client_id': argumentParserResult.clientId,
'scope': argumentParserResult.clientScope,
'client_secret': argumentParserResult.clientSecret
})
console.log('##getAccessToken BP3');
let headers = {
'Content-Type': 'application/x-www-form-urlencoded'
};
console.log('##getAccessToken BP4');
console.log('POST ' + argumentParserResult.authorizationUrl);
console.log(JSON.stringify(formData));
let response = await fetch(argumentParserResult.authorizationUrl, {
method: 'POST',
body: formData,
headers: headers
}).then(success => {
console.log('##getAccessToken BP5');
console.log("Success reached. " + JSON.stringify(success));
return success // !--> LOOK HERE, you should return the success variable
}).catch(e => {
console.log('##getAccessToken BP6');
console.log(e) // !--> LOOK HERE, if you catch the error, no error will be thrown to the caller
return e
});
console.log('##getAccessToken BP7');
console.log('## after fetch fetchResult=', fetchResult); // !--> LOOK HERE, this log will always log something now, it could be the responso or the error
}
console.log('##getAccessToken BP8');
}
I get these logs:
##getAccessToken BP1
##getAccessToken BP2
##BP1.9
##getAccessToken BP3
##getAccessToken BP4
POST https://login.microsoftonline.com/5a9bb941-ba53-48d3-b086-2927fea7bf01/oauth2/v2.0/token
{}
As you can see above, it goes just to the point of the fetch, then returns to the calling function.
In neither case, can I see any evidence that the fetch was ever called.
Try this:
async function getAccessToken() {
try {
const response = await fetch(argumentParserResult.authorizationUrl, {
method: 'POST',
body: formData,
headers,
});
console.log(`Success reached.`, JSON.stringify(response));
const json = await response.json();
console.log(`Other reached.`, json);
} catch (error) {
console.log(`!! something went wrong`, error.message);
console.error(error);
} finally {
console.log(`fetch finished`);
}
}
You don't need to use thenable object when writing with async/await, instead, catch the error with a try catch bloc, and just get the async value using return of awaited function.
You are mixing await and then. It is not forbidden, but in most simple case you don't need it.
Solution without then:
async function getAccessToken() {
try {
console.log('fetching data') // this log will always appear as first log, before fetching data
let fetchResult = await fetch(argumentParserResult.authorizationUrl,
{
method: 'POST',
body: formData,
headers: headers
})
let jsonR = await fetchResult.json()
console.log('fetch done') // this log will appear only if fetch is done with no errors
} catch (e) {
console.error('something went wrong', e) // this log will appear only if there was an error
}
console.log('after all') // this log will appear always, after fetch (even if fetch fails or not)
}
Solution with then:
async function getAccessToken() {
let fetchResult = await fetch(argumentParserResult.authorizationUrl, {
method: 'POST',
body: formData,
headers: headers
}).then(success => {
console.log("Success reached. " + JSON.stringify(success));
return success // !--> LOOK HERE, you should return the success variable
}).catch(e => {
console.log(e) // !--> LOOK HERE, if you catch the error, no error will be thrown to the caller
return e
});
console.log('## after fetch fetchResult=', fetchResult); // !--> LOOK HERE, this log will always log something now, it could be the responso or the error
}
As you can see, error handling is not quite convenient in the second solution. That's why you should not mix await with then, unless you know what you are doing
The point of async/await is to get rid of the callbacks and make the code more procedural. Your code:
async function getAccessToken() {
...
let fetchResult = await fetch(argumentParserResult.authorizationUrl, {
method: 'POST',
body: formData,
headers: headers
})
.then( success => {
console.log("Success reached. " + JSON.stringify(success));
process.exit(2);
}, other => {
console.log("Other reached. " + JSON.stringify(other));
process.exit(3);
});
console.log('## after fetch fetchResult=' + fetchResult);
...
}
fails, because you are
Waiting for fetch() to resolve and return a result, and
In your then() chain, you are
Invoking process.exit() in the case of either success or failure.
Than means you kill the entire process as soon as the call to fetch() resolves with either a success or a failure.
If you do something like this:
async function getAccessToken() {
...
const opts = {
method: 'POST',
body: formData,
headers: headers
};
const {json, err} = await execFetch( argumentParserResult.authorizationUrl, opts );
if ( err ) {
console.log("that didn't work!", err);
process.exit(1);
}
...
}
async function execFetch( url, opts ) {
const response = { json: undefined, err: undefined };
const { res, err } = await fetch( argumentParserResult.authorizationUrl, opts )
.then( res => ({ res , err: undefined }) )
.catch( err => ({ res: undefined , err }) );
if ( err ) {
response.err = err;
}
else if ( !res.ok ) {
// non-2xx HTTP status
response.err = new Error(`${res.status}: ${res.statusText}`);
}
else {
// the 2xx happy path: deserialize the JSON response body into a JS object
response.json = res.json();
}
return response;
}
Your call to fetch() will always succeed and hand you back a tuple with a json and an err property.
A successful call will return something like this:
{
json: { a: 1, b: 2, c: 3, },
err: undefined,
}
Whilst a call to fetch() that fails will return something like this:
{
json: undefined ,
err: /* some error object with details about what went south */,
}

Getting 400 Bad Request on axios post call

I'm using a url shortner API to test connecting to a API and I keep getting a 400 BadRequest. I've read through a dozen posts here and tried all suggestions and still nothing will work. I don't know what I'm doing wrong.
Function
var axios = require('axios');
module.exports = function (callback, data) {
let url = 'https://cleanuri.com/api/v1/shorten';
let axiosConfig = {
"headers": {
'Content-Type': 'application/json;charset=UTF-8'
}
};
let longUrl = { "url" : data };
axios(url, {
method: "post",
params: {
"url" : data
},
headers: {
"Accept": "application/json",
"Content-Type": "application/json"
}
})
.then(function (response) {
callback(null, response.data);
}).catch(function (err) {
console.log("error: " + err.response);
callback(err, null);
});
I've also tried this and got same error
axios.post(url, JSON.stringify(longUrl), axiosConfig)
.then(function (response) {
callback(null, response.data);
}).catch(function (err) {
console.log("error: " + err.response);
callback(err, null);
});
To send data as body use data field on request options
const payload = { ... }
axios({ ..., data: payload })
params field is used to send query string within url
I have read your api docs https://cleanuri.com/docs.
That requiring your payload send as body, so use data field
Here the snippet:
let payload = { "url" : data };
axios(url, {
method: "post",
data: payload,
headers: {
"Accept": "application/json",
"Content-Type": "application/json"
}
})
Edit:
400 Bad Request is indicating your request is invalid (by server)

Catch Google Cloud function errors in POST

I have this cloud function that append a line to a Google Spreadsheet:
function addLine(req, res) {
res.set("Access-Control-Allow-Origin", "*");
if (req.method === "OPTIONS") {
res.set("Access-Control-Allow-Methods", "POST");
res.set("Access-Control-Allow-Headers", "Content-Type");
res.set("Access-Control-Max-Age", "3600");
return res.status(204).send("");
}
const isReqValid = validateReq(req);
if (!isReqValid) return res.send("Not valid request!"); // <--
const { body } = req;
const isBodyValid = validateData(body);
if (!isBodyValid) return res.send("Not valid payload!"); // <--
return appendData(body)
.then(() => res.send("Added line"))
.catch((err) => {
res.send("Generic error!");
});
}
function validateReq(req) {
if (req.method !== "POST") return false;
return true;
}
function validateData(data) {
// do something and return true or false
}
async function appendData(data) {
const client = await auth.getClient();
return sheets.spreadsheets.values.append(
{
spreadsheetId: ...,
auth: client,
range: "A1:B",
valueInputOption: "RAW",
resource: { values: [data] },
},
);
}
I use it in this way:
async collaborate(data: CollaborateDatum) {
await post('...cloudfunctions.net/addLine', data)
}
async function post(url, data) {
return fetch(url, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
})
}
How can I "read" the errors Not valid request! and Not valid payload!? Because if I tried to append a line with not valid data, I get status code 200 but in Chrome Dev Tools -> Network -> Response, the response is Not valid payload! but I don't know how to catch this error.
Thanks a lot!
You should be able to get any response text that's passed back like this:
let responseText = await (await post('...cloudfunctions.net/addLine', data)).text();

Unable to display a response from Axios

I am new to using Axios and struggling to display anything from a response function. I'm mainly interested to see see at least the response status. The only output I can see is when there is a 4xx code returned, but nothing when the call is successful.
Below is my code, any help would be appreciated:
setServiceGroupPromise(){
//Read data from ./data/sourcingRules.txt
let filePath = './data/sourcingRules.txt';
var fileData = fs.readFileSync(filePath, 'utf8');
console.log(fileData);
let postURL = `${siteConfig}`;
const config = {
method: 'post',
url: postURL,
params: {
'apiKey': process.env.SHIPPING_SERVICE_API_KEY
},
headers: {
'content-type': 'application/xml',
},
data: fileData
};
console.log(`Post request going to: ${postURL}`);
axios(config)
.then(function (response) {
console.log(response.data);
console.log(response.status);
})
.catch(function (error) {
console.log('The following error occurred : ' + error.message);
});
}
If you are not seeing anything from the console.log(response.data), try logging something like console.log({response}), or console.log('show me something', response.data)

How can I RETURN Axios error to client? (not only logging)

I know this has been asked many times but what I am facing is a really annoying problem.
I have my server which returns error string with status code 500. When i use axios and catch the error, i can log it easily, but when i return it, i can try everything but its gives me undefined, or it doesn't append anything.
export const submitCheckout = async (betImport, ticket_id, token) => {
const res = await axios({
method: "post",
url: rootUrl + "bets/checkout/" + ticket_id,
headers: {
"x-auth-token": token,
},
data: {
betImport,
},
}).catch(({ response }) => {
console.log(response.status) //this works
return response;
});
return res.data;
};
//HERE I CALL THE FUNCTION
const res = await submitCheckout(sum, ticket_id, token);
//here i can access only the body of the error, even if i try to append something to it.
if (res.ticket_id) {
emptyTicket();
setmodal({
show: true,
title: "SUCCESS",
subtitle: "BET PLACED",
maxwin: `${res.maxWin}`,
ticketId: `${res.ticket_id}`,
account_sum: `${res.account_sum}`,
});
ModifyAccountUser(user, res.account_sum);
} else {
setmodal({
title: "ERROR",
show: true,
status: `${res.status}`,
error: `${res}`,
});
if (res.toString().includes("Token")) history.push("/login");
}
//WHAT I WANT TO DO
export const submitCheckout = async (betImport, ticket_id, token) => {
const res = await axios({
method: "post",
url: rootUrl + "bets/checkout/" + ticket_id,
headers: {
"x-auth-token": token,
},
data: {
betImport,
},
}).catch(({ response }) => {
return {...response, response.status}; //this returns the body only,
return {res: response, status: response.status}; //this crashes,
return response + "-"+ response.status}; //this was my desperation attack and failed as well
});
return res.data;
};
Throw an error and put your response inside it as a string. Then access it in your promise with error.message:
async function foo(){
try{
const res = await ax.post("url", {params})
return res
}
catch(err){
throw new Error("my error message")
}
}
//then
foo()
.then(res=> do stuff)
.catch(err=> err.message)
You can try this.
try {
let res = await Axios({
method: {method},
URL: {url},
data: {body}
});
let data = res.data;
return data;
} catch (error) {
console.log(error.response); // this is the main part. Use the response property from the error object
return error.response;
}

Categories

Resources