I am not sure how I am supposed to get the errors that come from the backend when a POST request is sent to the backend. If I use plain axios calls, I can simply get the errors from the response object in the catch block with:
error.response.data.errors
But when using Redux and using createAsyncThunk method, on a 400 status code from the server, a rejected action is dispatched and the error object I get is a generic one like so:
{
message: "Request failed with status code 400"
name: "Error"
stack: "Error: Request failed with status code 400\n...."
}
How can I get the server errors, just like using axios?
You can make use of the rejectWithValue function from redux-toolkit to include the server error as the payload property of your rejected action.
It would be something like this (untested code because I’m on my phone)
const myAction = createAsyncThunk(
‘actionName’,
async ( arg, {rejectWithValue} ) => {
try {
const res = await axios.post(…);
return res.data;
} catch (error) {
return rejectWithValue( error.response.data.errors );
}
});
I think what you can do is add an additional check for the errors and also wrap the axios post request with a try catch block.
Note : In your case the request is failing so I guess there must be some error with the way you are making a request.
Related
I have a form data which on submit I a sending to backend if there is an error I have process the error and show it on page. Request is getting posted fine but when getting a backend response I never go to catch error loop. Appreciate any help in resolving this.
Thanks
const [errorMessage, setErrorMessage] = useState('')
mutate(
`${api}`,
fetcher('POST', `${api`, body: JSON.stringify(data))
)
.then((data) => {
... do something
})
.catch((error) => {
setErrorMessage(data.error.message)
console.error(error)
})
}
backend response data :
{"trace_id":"abc","errors":[{"code":122,"message":" Error While
Submitting."}]}
The .catch clause will only fire if there is an error executing the network request. But in this case, it's working - it sends a request and gets a response. So only the then clause is fired. However, the response contains an error.
There are a few ways to make it so the error response gets 'caught' - either you configure your graphql library to look inside each response to check for 'errors' property to be non-empty and throw, or you can do that inside the then clause in your example.
I am not sure if I am just doing something wrong or if this is actually not working. I want to display the original publication error on the client, in case I catched one:
Meteor.publish('somePub', function (args) {
const self = this
try {
// ... publication logic
catch (pubErr) {
self.error(pubErr)
}
})
On the client I am "catching" this error via the onStop callback:
Meteor.subscribe('somePub', args, {
onStop: function (e) {
// display e to user
}
})
However, while on the server the pubErr is a Meteor.Error and according to the documentation it should be sent to the client, the client just receives a generic sanitized error message:
on the server
{
stack: "useful stack of actual method calls",
error: "somePub.failed",
reason: "somePub.invalidArguments",
details: { arg: undefined }
}
on the client
{
stack: "long list of ddp-message calls",
isClientSafe: true,
error: 500,
reason: "Internal server error",
details: undefined,
message: "Internal server error [500]",
errorType: "Meteor.Error"
}
Note: I also tried to add the error to itself as sanitizedError field, as in the documentation mentioned, but no success either.
Am I missing something here?
Actually I found the answer to the issue after being pointed into the right direction.
The example code works fine on a new project, so I checked why not in my project and I found, that I did not surround the arguments validation using SimpleSchema by the try/catch (unfortunately my question was poorly designed as it missed this important fact, mainly because I abstracted away the schema validation from the publication creation):
Meteor.publish('somePub', function (args) {
pubSchema.validate(args) // throws on fail
const self = this
try {
// ... publication logic
catch (pubErr) {
self.error(pubErr)
}
})
So I thought this could not be the issue's source but here is the thing: Simple Schema is not a pure Meteor package but a NPM package and won't throw a Meteor.Error but a custom instance of Error, that actually has the same attributes (error, errorType, details) like a Meteor.Error, see this part of the source code of a validation context.
So in order to pass the correct information of a SimpleSchema validation error to the client you should
wrap it in a try/catch
add the isClientSafe flag to it
alternatively convert it to a Meteor.Error
Attach a custom Meteor.Error as sanitizedError property to it
I work with vue and go for frontend and backend respectively. I send post request to my server and get 403 error code message(notAllowed). But in postman I get the objects and is fine.
Vue and Vuex
My axios post request:
const response = await this.$axios.post(`http://localhost:8000/v1/org/${params.organization}/kkms/${params.kkm}/closeShift`,{
headers : {
'token' : this.state.token.value
}});
I know I should also use other properties like 'Content-Type' and etc in headers, but know it works well with only "token" property in the other requests. I want to know whether problem in backend or frontend?
It seems you have a mistake in the axios request.
You are receiving a 403, that means you are not authorized (or sometimes something else, check the comments in the question and down here ).
As can be found in axios docs, the post request looks like this:
axios.post(url[, data[, config]]).
It accepts the config (so the headers) as THIRD parameter, while you are setting it as second parameter. Add an empty FormData object as second param, and just shift your config to the third param.
const fakeData = new FormData();
const response = await this.$axios.post(`http://localhost:8000/v1/org/${params.organization}/kkms/${params.kkm}/closeShift`,
fakeData,
{
headers : {
'token' : this.state.token.value
}
});
I am trying to fetch local api made in asp.net api which is running in https://localhost:44388/. When I tried to fetch get request it responds ok but return html not json. The problem might occur by two reasons:
1.typo in url (But I checked in my browser, it worked)
2.Server restart needed
What might be the problem with my code?
componentDidMount(){
var proxyUrl = "http://127.0.0.1:3000/";
var targetUrl = "https://127.0.0.1:44388/api/product/getproducts";
fetch(proxyUrl+targetUrl, {
method:'GET',
headers:{
'Access-Control-Allow-Origin':'*',
'Access-Control-Allow-Mehods': '*',
'Access-Control-Allow-Headers': '*',
'Access-Control-Allow-Credentials':'*',
'Content-type':'application/json'
}
})
.then(data=>{
if(!data.ok){
throw new Error("Error");
}else{
return data.json();
}
})
.then(data=>this.setState({products:data}))
}
when you give parameter as:proxyUrl+targetUrl,
actually the url which you have called is :
http://127.0.0.1:3000/https://127.0.0.1:44388/api/product/getproducts
which does not seems to be correct.
i think the structure of url you'v given to fetch function is wrong.
When I am hitting this function directly by URL it worked and this insert data in Firebase object
addCountry: function (req, res) {
var ref = db.ref();
var usersRef = ref.child("country");
usersRef.push({
name: 'United States',
is_deleted: 0,
});
return res.view('city-listing');
}
But when I called this function by the form submit post method then it will throw the error:
"error: Sending 500 ("Server Error") response:
Error: Can't set headers after they are sent."
Error: Can't set headers after they are sent.
Error occurs if you are sending the view more than once in the same route handler . It had happened to me once too. Check that you don't have more than one view related rendering which might execute twice.