Incorrect short-circuiting of "task runner"?
tdd opened this issue · comments
Hi Nicholas,
Location: Chapter 11 > Page 238 > "Promise-Based Asynchronous Task Running" > code at top of page
The following code block almost at the top puzzles me:
if (err) {
result = task.throw(err);
return;
}
You're side-stepping (pun intended) the call to the next step()
, which doesn't seem right. In fact, your next take on it does take care to step()
after the task.throw(err)
.
What am I missing here?
I wouldn't call it incorrect per se. It it inconsistent though, using return
after error in the callback version, and using step()
after error in the Promise version.
How I understand what happens in case of error, in both versions:
- Runner gets the generator and obtains iterator
- Runner gets the callback/promise object by running the first
task.next()
- The generator runs and yields once
- Runner calls the async function (
result.value
) - The async function fails (the runner either sees
err
on callback, or ends up incatch
clause of the Promise) - And here's the problem – the
task.throw
calls the generator, which, in this example, doesn't handle the error thrown at it, and thus the error bubbles up the stack. Given that the error isn't caught anywhere in the generator or the runner, program execution halts, and execution never gets to the followingreturn
/step()
in the runner, so it doesn't really matter whetherstep()
is there or not. Even thereturn
is unnecessary.
However, if the generator handled the error, then it would make sense to have either return
or step()
. I see this as a choice when designing the runner. You can have either:
- with
return
– a runner which stops executing code of the task after the task encounters and handles an error – strange behaviour, I can't imagine a use case (not saying one does not exist) - with
step()
– a runner which continues execution of the task if the task can handle its errors – which is behaviour I would expect
The decision to abort (handling or not handling the error and returning or not returning) should be up to the task, not up to the runner.
So, I agree that the use case with return
is at least strange, if not incorrect :)
(Or I'm just completely misunderstanding something ¯\_(ツ)_/¯ )