-
Notifications
You must be signed in to change notification settings - Fork 74
[async/await] allow state machine to re-throw errors #423
Comments
I guess this would be possible to do by creating a custom implementation of |
Uhm, sounds rather complex. Actually I've fixed it by forking the repo and having the following added in IEnumerable<JsVariableDeclaration> declarations = new[]
{
JsStatement.Declaration(_stateVariableName, JsExpression.Number(0)),
JsStatement.Declaration("$$ex", null) // <- adds: "var $$ex;"
};
...
// adds: if ($$ex !== undefined) throw $$ex;
var ifs = JsStatement.If(
JsExpression.NotSame(JsExpression.Identifier("$$ex"),JsExpression.Identifier("undefined")),
JsStatement.Throw(JsExpression.Identifier("$$ex")),
null);
guarded = JsStatement.Block(ifs, guarded);
currentBlock.Add(JsStatement.Try(guarded, @catch, @finally)); So any Has this workaround any chance of being supported officially? |
Maybe. How generic is the use case? Is it useful for other use cases as well or is it very tailored to Q? If it has any kind of generic value, I guess we could do this, but only if the $$ex variable is used in the body. |
I did a quick implementation of another promise library (lahmatiy/es6-promise-polyfill) just to see if it's a generic case. Well, the workaround was needed with this library too (and generally speaking, it's needed to all libraries that follow the ES6 promise specs). To sum up the problem:
The "workaround":
example [InlineCode("{this}.catch(function(err){{$$ex=err; $sm();}})")]
public extern Promise GetAwaiter(); Of course to make it work, any promise implementer has to adhere strictly to this behaviour. I'll prepare a PR so we can discuss it more in detail (btw, I haven't found a |
OK, so then it is probably a good idea to do this. I do, however, think that we should only declare the $$ex variable if it is actually used. |
Unfortunately I have no idea how to detect when |
The idea to do this is to derive from |
I'm stuck on this problem when trying to make async/await work seamlessly with JavaScript promises (kriskowal/Q library, but I guess it's the same with other promise libraries as well).
The problem is that exceptions inside a promise are captured and eventually rethrown on the "next tick" of the event loop (with a
setTimeout()
call). Unfortunately, that causes that they are not caught by the state machinetry...catch
block, making them impossible to handle.I tried all possible tweaks, but despite all my efforts I was unable to make it work.
The only possible solution I've found requires a very small modification to the current state machine:
This would allow to re-enter the state machine and rethrow from local site any caught error.
And to take advantage of this modification, one would have to:
ex
variable to exception that needs to be rethrown$sm()
callFor example with this custom
GetAwaiter()
from within aFuture
object:that transpiles into:
So my question is, does the above modification make any sense? Is it acceptable/doable? Is there a better way to handle all this?
Any suggestion is welcome.
The final goal of this effort is to use JavaScript promises with
await
without breaking the current semantic.The text was updated successfully, but these errors were encountered: