Comments (7)
Ah, good catch!* This should be an easy fix.
*totally unintended pun, I swear
from flummox.
:)
from flummox.
Hmm, well, this works:
return promise
.then(
body => {
setTimeout(() =>
this._dispatch({
actionId,
body,
async: 'success'
})
, 0);
},
error => {
setTimeout(() =>
this._dispatch({
actionId,
error,
async: 'failure',
})
, 0);
return Promise.reject(error);
}
);
but it feels pretty hacky. And it means if you await
an async action, the action hasn't dispatched yet. Not good.
The other option is to use a catch handler
return promise
.then(
body => {
this._dispatch({
actionId,
body,
async: 'success'
});
},
error => {
this._dispatch({
actionId,
error,
async: 'failure',
});
return Promise.reject(error);
}
)
.catch(error => setTimeout(() => { throw error }, 0));
but that also feels hacky because 1) promise-based operations aren't supposed to throw errors, and 2) the error is being thrown during a different turn of the event loop from when it actually occurred.
I think a better way to handle this would be to have Flux emit an error
event, the same way it emits a dispatch
event. How does that sound?
from flummox.
Released as part of v2.12.0. If you want to "un-swallow" the errors, you can do something like this:
flux.addListener('error', error => setTimeout(() => { throw error }, 0));
I would only do this during development, though, if at all.
from flummox.
Hey man, sorry about the late response here but I've been busy.
I saw you fix and it works.
But..
Even though I totally agree with you when you say that a promise is not supposed to throw, the reality is that it potentially could.
Since you are calling something external like the Dispatcher#dispatch, I think the best approach would be to surround that call with a try/catch block.
This way we can catch the exception and rethrow it in the next tick.
Doing this seems to be the normal behaviour, I mean that if an error occurs the right thing to do is not hiding it, but make the system aware of it, in a natural way (rethrow). Then the developer will be in charge of handling it.
McFly does something similar.
https://github.com/kenwheeler/mcfly/blob/9a45f3e8095d40685a09594256148d58bc3a2143/src/Action.js#L6
Hiding the error and make it catchable only subscribing to the error event on the flux instance feels a bit weird to me, especially if I don't know that I can do it just because I'm too lazy to read the docs :)
This is just my 2 cents, your solution work pretty well by the way.
Handling errors in promises is always a mess :)
from flummox.
even though [...] a promise is not supposed to throw, the reality is that it potentially could.
Not unless you do it intentionally using setTimeout()
. All errors that occur inside a .then()
callback are (by design) gobbled up and turned into a rejected promise. It's part of the spec.
I mean that if an error occurs the right thing to do is not hiding it, but make the system aware of it, in a natural way (rethrow)
That's the natural way to handle errors in synchronous code, because you can use try-catch. But try-catch doesn't work for errors that occur in separate ticks of the event loop, hence the common Node-style pattern of passing an error object as the first argument to a callback. (Even using ES7 async functions, which do allow you to use try-catch through some wonderful generator and promise magic, if an unhandled error occurs, the function returns a rejected promise.)
With promises, the natural way to handle errors is to reject. I agree it's kind of weird, and probably the most contentious part about promises, but (since error-throwing is a synchronous operation) it makes sense if you think of promises as occurring in a totally separate time dimension from its calling context.
In practical terms, the reason "rethrowing" an error using setTimeout()
is bad is because there's no way to catch it after that, because it happens during the next tick. Which is obviously bad.
McFly does something similar.
Tell me, how would you catch the error on line 11 after it's thrown? :)
I think the best approach would be to surround that call with a try/catch block.
Wrapping in a try-catch block has the same effect as the second code snippet from my comment above.
All of this is not to say that I'm not open to figuring out a better way to handle errors in Flummox. I just don't think rethrowing is the right solution. For now, I would recommend using the error event so you can make your own decisions.
from flummox.
Tell me, how would you catch the error on line 11 after it's thrown? :)
I guess the only way do to so is to usewindow.onerror
handler.
The one we are discussing about is probably the most controversial Promise part :)
Anyways, the goal of the issue was to have the ability to notice errors, this way we are now able to log somewhere errors deriving from a developer syntax error for instance. And this is good 👍
from flummox.
Related Issues (20)
- how to get a child component input value HOT 1
- Missing getActionsAsObject from Actions HOT 5
- Incorrect params passed to async begin handler HOT 1
- More topic guides needed in doc HOT 1
- Context differs problem
- Do not pass flux prop to components wrapped with `connect` HOT 6
- Use Redux HOT 6
- Explanation in README as to why a switch to Redux should be made HOT 5
- Import flummox/component fails with 4.0.0-rc1 HOT 1
- unable to make flummox work with react-router 1.0.0-beta3 HOT 2
- Actions.js grabs all console logs HOT 4
- Wrong link in why-flux-component-is-better-than-flux-mixin.md
- Considering the numbers HOT 1
- Support for React 0.14 HOT 17
- How to only use custom stateGetter for subset of subscribed stores HOT 1
- Maintain module? HOT 4
- FluxComponent does not work on IE10 HOT 24
- Flummox 3.6 is incompatible with IE8 HOT 3
- TestUtils removed from NPM HOT 2
- Deprecation warning with React 15.5 HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from flummox.