React useQuery - useMutation onError not catching - axios

I'm using a combination of Axios and react-query to make a POST request to a server that may answer with response code 400 and validation errors.
export const axiosDefault = axios.create({
baseURL: API_LINK,
headers: {
'Content-Type': 'application/json'
},
})
const contactMutation = useMutation(
(data) => axiosDefault.post('/contact', data),
{
onSuccess: (response) => {
console.log('Success', response)
},
onError: (error) => {
console.log('Error', error)
}
}
)
However, when calling contactMutation.mutate(someData) the error response from the server does not get processed by the react query library and instead propagates upward. Neither the onSuccess or onError handlers get called, the isError property of the mutation is also not set.
I've spent hours tearing my hair out over this, what am I doing wrong?

hi i also had same issue i solved by wrapping api function to try/catch block and throw the catched Error.
(data) => {
try {
axiosDefault.post('/contact', data),
} catch (error) {
throw error
}
}

Related

How to get headers from AxiosResponse-Observable?

Using NestJS, Axios returns an Observable<AxiosResponse>.
How can I get the headers of a GET- or HEAD-Request?
Lets say I make a HEAD-request:
import { HttpService } from '#nestjs/axios';
const observable = this.httpService.head(uri);
How can I get the headers from the result?
Update:
I found a nice workaround that just works with a single line of code.
There is another library called https with is more powerful:
import http from "https";
await http.request(uri, { method: 'HEAD' }, (res) => {
console.log(res.headers);
}).on('error', (err) => {
console.error(err);
}).end();
The headers of the response are available in the subscribe callback with the headers property.
this.httpService.head(uri).subscribe(res => {
console.log(res.headers)
});
Playground
According to https://github.com/axios/axios#request-config:
For request headers you should use something like this:
this.httpService.axiosRef.interceptors.request.use(function (config) {
// Do something before request is sent
console.log(config);
return config;
}, function (error) {
// Do something with request error
return Promise.reject(error);
});
You should use it onModuleInit (to prevent working a few interceptors in a time)
Also you can make own module like in this answer: https://stackoverflow.com/a/72543771/4546382
For the response headers you can just use response.headers

axios DELETE request with body in Nuxt.js

I have an app built with Nuxt.js. To get data from the API I use axios, namely #nuxtjs/axios. All request work fine but for the DELETE method.
My syntax is the following:
async removeItemFromCart(productId) {
const accessKey = await this.$store.dispatch('fetchUserAccessKey');
try {
this.$axios.delete(`/api/baskets/products?userAccessKey=${ accessKey }`, {
data: {
productId: productId
}
})
} catch (error) {
console.log(error);
}
},
However, in the console I always get the following error: createError.js?2d83:16 Uncaught (in promise) Error: Request failed with status code 400
I tried to use params instead of data, but to no avail. What am I missing here?
It seems that there's an issue with axios: when you use delete method with body, it either doesn't include payload, or deletes Content-type: 'application/json' from headers. To solve the issue, I used .request instead of .delete (according to https://github.com/nuxt-community/axios-module/issues/419)
this.$axios.request(`/api/baskets/products?userAccessKey=${ accessKey }`, {
data: {
productId: productId
},
method: 'delete'
}).

Cancelling promise in nuxt-axios response interceptor

Basically, my question is the exact one here https://github.com/axios/axios/issues/583. It can be done via throw new axios.Cancel('Operation canceled by the user.');.. But how can I do this in nuxt axios module?? I can not see it in the document and I tried $axios.Cancel('Error') but returned $axios.Cancel is not a constructor
Basically, the something like the snippet below is what I am looking for:
axios.interceptors.response.use(function (response) {
throw new axios.Cancel('Operation canceled by the user.');
}, function (error) {
return Promise.reject(error);
});
Emphasis on throw new axios.Cancel
While #nuxtjs/axios does not expose axios.Cancel, you could still import axios directly to get that symbol. Note axios is already a dependency of #nuxtjs/axios, so no extra dependency necessary.
Example (tested with #nuxtjs/axios v5.11.0):
// plugins/axios.js
import { Cancel } from 'axios'
export default function ({ $axios }) {
$axios.onResponse((response) => {
if (response.code !== 200){
throw new Cancel(response.msg)
}
})
}
With nuxt/axios v5.8.0 IsCancel available
v5.8.0 add CancelToken and isCancel to axios instance
Seems like nuxt-axios does not have any exact equivalent but I found a work around.
plugins/axios.js
export default function({ $axios, req, store, redirect, app }, inject) {
// const source = $axios.CancelToken.source()
const timeout = process.env.API_TIMEOUT || 10000
const errorHandling = function(error) {
console.log(`API ${error}`)
return new Promise(() => {})
}
$axios.onResponse((response) => {
// Any condition that could be considered an response based on standard response
if(response.code !== 200){
throw response.msg
}
})

Http failure response for (unknown url): 0 Unknown Error","error":{"isTrusted":true}}

I have on my logs this error which I tried to reproduce with different devices but I have never been able to.
{“headers”:{“normalizedNames”:{},“lazyUpdate”:null,“headers”:{}},“status”:0,“statusText”:“Unknown Error”,“url”:null,“ok”:false,“name”:“HttpErrorResponse”,“message”:“Http failure response for (unknown url): 0 Unknown Error”,“error”:{“isTrusted”:true}}
This error comes from this function which calls to google api:
return new Promise((resolve, reject) => {
this.http
.post(
“https://automl.googleapis.com/v1beta1/projects/XXXXX/locations/us-central1/models/XXXXXXXXXX:predict”,
file,
{
headers: {“Authorization”:"Bearer "+accessToken}
}
)
.timeout(600000)
.map(res => res)
.toPromise()
.then(
//call then instead of subscribe to form the promise chain.
data => {
resolve(data);
},
err => {
reject(err);
this.utilsService.registerEvent(err,userId,version)
}
);
});
}
I don’t know how to solve it and how can reproduce it. It is generating 10 or 15 errors a day. Can anybody help me? Thanks!

Axios in lambda not waiting for response

I am invoking axios post method in aws lambda. Most of the times lambda does not return any result.logs show the following results
START RequestId: ac92d268-d212-4b80-a06c-927922fcf1d5 Version: $LATEST
END RequestId: ac92d268-d212-4b80-a06c-927922fcf1d5
But some times lambda return expected results. Looks like lambda is not waiting for axios to complete. below is lambda code.
var axios = require('axios')
exports.handler = async (event, context,callback) => {
axios.post('https://example.com/testapi/api.asmx/GetNames', {})
.then((res) => {
console.log(JSON.stringify(res.data,null,2))
callback(null,'success');
})
.catch((error) => {
console.error(error)
callback(null,'error');
})
};
Your handler is async which means it will run asynchronously and return a Promise. This means that your function is being terminated before your code actually runs.
Since axios already works with Promises and your method already is async, you don't need to change too much. This will fix the problem:
const axios = require('axios')
exports.handler = async (event) => {
try {
const res = await axios.post('https://example.com/testapi/api.asmx/GetNames', {})
console.log(res)
return {
statusCode: 200,
body: JSON.stringify(res)
}
} catch (e) {
console.log(e)
return {
statusCode: 400,
body: JSON.stringify(e)
}
}
};
You can understand more around async/await if you want to.
I was having a similar issue where I make a 3rd party API call with Axios in Lambda, after spending almost a day noticed that my lambda had 6 seconds default timeout. Sometimes the response from the api was getting longer than 6 seconds and it was causing a 502 response.