Open franciscop-sc opened 2 years ago
I have a similar situation. I would love to be able to turn off either the error message or have it catch the error so that it doesn't propagate. I can see use cases where you want both so I'm not sure the best idea is to ALWAYS resolve the promise successfully. But my particular flavor of function code feels like it needs some hacky-ness to handle this where an option flag might help me out.
Example of code:
const handleSaveObject = async () => {
try {
if (!somevalue) throw new Error('Uh oh no value found');
if (!someOthervalueCheck) throw new Error('We do not like this value');
await toast.promise(
updateObject(someValue),
{
loading: 'Saving...',
success: 'Saved!',
error: (err) => err.message,
}
);
} catch (err) {
toast.error(err.message);
}
};
In this case, if updateObject throws an error 2 toasts will be shown because the updateObject function would be thrown sending the error to my catch block as well as the toast.promise showing the error message. Am I just missing a good way to handle this simply without adding another try/catch?
I'd be happy to contribute but I'm not sure what the best approach would be and what the default looks like. Maybe a stopErrorPropogation value in the options? or maybe if the error ValueOrFunction option is set to undefined/null, it rejects the error and if it's provided, then it "catches" the error and resolves successfully? I'm thinking the latter might make the most sense. If you don't provide the "settings" to handle the error then it essentially won't handle the error.
As a quick workaround, I've started to do this, which looks pretty wrong:
await toast.promise(...).catch((err) => null);
// Error IS handled, please see https://github.com/timolins/react-hot-toast/issues/157
However if I was reviewing code and someone else wrote that, and I didn't know how the promise() works internally (it does both, handle the error AND throw the error) I'd review the code wrongly as "please don't ignore errors".
This is a feature request based on some surprising behavior I found. Alternatively, a documentation request to make said behavior clear. I can help with either, but I'd like to know what @timolins and the library authors prefer to do first 😃
I expect that if the promise fails, then toast.promise should handle it internally. And it does in this case, since internally it calls
.catch()
:But notably, if we await for that
await toast.promise(...)
, now it throws! This will show thealert()
:Unfortunately this behavior is surprising IMHO, the toast should either handle errors in all cases (better) or throw errors in all cases (not preferred), whether we wait for it or not. Is the role of the popup considered as "error handled"? I'd say yes, since there's a explicit "error: ..." key there, so I'd expect that the second example not to throw the error.
This happens because
toast.promise()
conveniently returns a promise to know when it's finished. IMHO this promise should always resolve positively, since the error is already handled in the toast itself, and be used only for timing externally. So I'd change this code:For this one, so that if the promise has been caught then it will become resolved instead of rejected: