I'm trying to make an alert window saying there's an error, When trying to post a message offline. But the catch doesn't seem to ever work, Maybe it just works in other cases?
here's my code :
return (dispatch) => {
dispatch({
type: POST_TO_DB,
});
firebase.database().ref(locationInDB).push(object)
.then((data) => {
dispatch({
type: POST_TRADE_TO_DB_SUCCESS,
}); // success
})
.catch((err) => {
console.log("failed to post...")
dispatch({
type: POST_TRADE_TO_DB_FAILED,
}); // failed
});
};
Is there an alternative? Or am I doing something wrong?
When there is no network connection, the Firebase client will keep the pending write in memory until the network connection is restored, at which point it will complete the write.
The catch() clause is triggered if the write fails on the server, not when it can't complete.
Also see:
To detect if the client is connected to the Firebase backend, see Detect if Firebase connection is lost/regained
Firebase synchronisation of locally-modified data: handling errors & global status
Related
In our quasar application we have a few boot files, some of them can run into an exception which should block the application from starting normally, instead an error should be displayed.
Is there some best-practice for such a case? I didn't find much in the documentation.
My approach was the following, if an error occurs forward/redirect to an error page and display the error.
I need to somehow pass the error to the error-page:
passing the message as GET parameter would be a bad idea => XSS
I also cannot pass an error ID/Key because the error may come from a server with various messages
Storing the error in a vuex store does not work because the store is reset after reject() is called.
So I was thinking maybe there is a better way of doing handling errors in boot files?
Stop current booting and goto error-page...
Here is an reduced example which will end in the /error page but with the store.error empty, reject() will reboot the application reset the store.
export default ({ app, store, urlPath }) => {
// required to prevent invinite loop, the reject(url) will reboot application
if (urlPath.indexOf("error") !== -1) {
// TODO be more specific then indexOf("error")
return;
}
return new Promise((resolve, reject) => {
doSomeServerCommunication()
.then((result) => {
resolve();
})
.catch((e) => {
store.commit("appStore/updateError", e);
reject({ url: window.location.origin + "/app/error" });
return;
});
});
};
I'm not sure why my function is not exiting after running. The code does not exit execution after resolving a promise.
I am using Firebase Admin SDK to send a message with the following:
var message = {
data: {
score: '850',
time: '2:45'
},
topic: topic
};
admin.messaging().sendAll([message])
.then((response) => {
// Response is a message ID string.
console.log('Successfully sent message:', response);
})
.catch((error) => {
console.log('Error sending message:', error);
});
after printing to the console 'Successfully sent message:' the code console is still running and not return. What am I doing wrong?
For reference here is the signature of the firebase message send:
send(message: admin.messaging.Message, dryRun?: boolean): Promise<string>;
There might be something in the Firebase Admin SDK that is keeping the process from exiting. You can force the process to exit when you're done by simply adding process.exit(0) to the end of the then callback, if that's when you want it to terminate.
If you think this behavior is a bug, you can file it on the Firebase Admin SDK GitHub.
We're using the enterprise server side row model to fetch data from the server. We've implemented the IServerSideDatasource and, if the server errors, we call params.failCallback as recommended.
However, nothing happens on the grid. The loading spinner still is visible and there's no notification to the user about anything going wrong.
The 'onRowDataChanged' event fires, but it has no information about the status of the event.
Is there a recommended way to notify the user about the failure? Ideally I'd like to deal with this through ag-grid events rather than throw my own errors from the IServerSideDatasource or even the http client.
Is this possible?
I'm using a custom eventListener to catch failCallback calls and it works pretty well
In my main class:
onGridReady = params => {
this.gridApi = params.api;
this.gridApi.addEventListener('failCallback', this.onServerFailCallback);
this.gridApi.setServerSideDatasource(MyRemoteDataSource);
};
onServerFailCallback = params => {
console.error('onServerFailCallback', params);
}
In MyRemoteDatasource:
class MyRemoteDatasource{
getRows(params) {
fetchData(params).then(
response => {
params.successCallback(response.data);
},
error => {
params.failCallback();
params.parentNode.gridApi.dispatchEvent({
type: 'failCallback',
api: params.parentNode.gridApi,
columnApi: params.parentNode.columnApi,
error: error
});
});
}
}
output:
onServerFailCallback,
{type: "failCallback", api: GridApi, columnApi: ColumnApi, error: Error: Error inside fetchData() at stack trace…}
This problem annoys me, because I know it has something to do with me not understanding the issue properly - which makes it really hard to track down answers for, despite spending hours reading and trying different things.
My question/problem is this, I am saving a user to a mongodb database when they signup, my schema doesn't allow for duplicate emails, and sends me back an error. I am able to console log the error in the terminal, but I am having problems sending it back to the client. Or I'm having a problem doing something with it, if it comes back, I'm not too sure where in those two steps I am losing access to the error message.
Here is my POST route for saving the user:
router.post('/users', (req, res) => {
let body = _.pick(req.body, ['email', 'password']);
let user = new User(body);
user.save().then(() => { // this all works and will save the user, if there are no errors
return user.generateAuthToken();
}).then((token) => {
res.header('Authorization', `Bearer ${token}`).send(user);
}).catch((err) => { // This is where my problem is
console.log(err); // This will log the mongodb error here, about duplicate emails
res.status(500).send(err); // I'm trying to send the mongodb error message back to the client to display it on the screen (I will handle making the message friendly to read, once I can get this to work)
});
});
So my catch is getting the mongo error, and then I try to respond with it, by sending it to the client.
Here is my client side code:
axios({
method: 'post',
url: '/auth/users',
headers: {
'Content-Type': 'application/json'
},
data: {
email,
password
}
}).then((res) => {
console.log('this is the response', res);
if (res.status === 200) {
var authToken = res.headers.authorization.split(' ')[1];
authenticateUser(authToken);
this.props.history.replace('/dashboard');
} // This all works fine for a signup with no errors
}).catch((err) => {
console.log('Signup error:', err);
// I am expecting the above line of code to log the long Mongodb
// error message that I am sending back in my res.status(500).send(err)
// catch call from the server, but instead all I am getting is
// "Signup error: Error: Request failed with status code 500"
});
Either I'm not sending the error correctly, or I'm not handling it correctly when it comes back, but I have no idea which it is or why.
I can't even send back res.status(500).send('some string here') and access that string.
Thanks
Update
So I just checked in postman, by sending a POST that could cause the error, and I am getting the correct response sent through.
My server catch actually looks like this:
.catch((err) => {
res.status(500).send({message: err.message});
});
And the postman response body looks like this:
{
"message": "E11000 duplicate key error collection: authBoilerplate.users index: email_1 dup key: { : \"email#example.com\" }"
}
So I'm just not handling it correctly in my client side code, still at a loss though.
Thanks everyone, I was able to find the answer to my question, so I'm posting it here in the hope that it might help someone else.
I was definitely sending my custom error message back, I just wasn't handling it properly on the client side.
When I was using a catch call on the client and logging the error, I was expecting to see everything included in the error. It turns out that the error comes back with a response property error.response, and that is where all the messaging is.
So changing my catch call to this:
axios(//... send post in here)
.then(// ... same as in my question)
.catch((err) => {
console.log('error', err);
console.log('error response', err.response); // this is where the actual error response message is error.response.message
});
resulted in logging the stack trace and the error response:
error Error: Request failed with status code 500
at createError (eval at <anonymous> (bundle.js:541), <anonymous>:16:15)
at settle (eval at <anonymous> (bundle.js:847), <anonymous>:18:12)
at XMLHttpRequest.handleLoad (eval at <anonymous> (bundle.js:520), <anonymous>:77:7)
error response Object {data: Object, status: 500, statusText: "Internal Server Error", headers: Object, config: Object…}
I was still expecting to be able to see that I had access to that 'response' property by logging just the error, so if anyone has any insight into that, it would be great to include in the comments.
Another way of solving this is by converting the error to string.
.catch((err) => {
res.status(500).send(err.toString());
});
I'm using the following code to set up a listener for Firebase Database Ref:
export function listenToUserEventsFeed (userId, cb, errorCB) {
database.ref(`proUserEvents/${userId}`).on('value', (snapshot) => {
console.log('SNAPSHOT RECEIVED')
const feed = snapshot.val() || {}
const sortedIds = Object.keys(feed).sort((a, b) => feed[b].createdAtTimeStamp - feed[a].createdAtTimeStamp)
cb({feed, sortedIds})
}, (error) => {
console.log('SNAPSHOT ERROR: ', error)
})
}
But the console.log('SNAPSHOT ERROR: ', error) never runs if I test using no internet connection. Am I missing something or is there something wrong in my code? I essentially want to pass down the error to the errorCB() function.
The error callback will only be called in case of an error, i.e. when your current client has no permission to read the data it is trying to read.
Not having an internet connection is not an error.
If you want to detect whether there is an internet connection, listen for .info/connected.
Related:
Firebase Handling disconect to database
Android Firebase - "onDataChange" And "onCancelled" Not Being Called With No Internet Connection
How to Catch Error When Data is not Sent on Angularfire when adding data to firebase?