5 ms·
This is a fundamental issue with multitasking, in that an independent task will have its own stack, so errors can't propagate up the stack of the function that
by rictic 9y ago
This is a fundamental issue with multitasking, in that an independent task will have its own stack, so errors can't propagate up the stack of the function that started the task.
e.g. consider this python code:
def start_task():
Thread(do_task).start()
What happens if do_task throws an exception? The exception can't propagate up from start_task because start_task may have returned when the exception is thrown.
At some point you have to join your threads, and you have to await/then your promises, otherwise there's no well defined place in your program for the exception to go.
Linters can help with this. tslint is one example, I believe it can give a warning for unhandled promises.
`p` will reject, any function that awaits p will reject. The error is that you've fired off an asynchronous task but you don't have any code that cares about the result of that asynchronous task (and the stack of any code that
- codedokode 9y ago> otherwise there's no well defined place in your program for the exception to go. I don't see the problem with that. Unhandled exceptions can occur at any place of your program. I also don't see why the unhandled exception from the background thread cannot terminate main thread. Why not? That is how unhandled exceptions are supposed to work. Terminating the program is the optimal default behaviour for any error in my opinion. This way you won't miss them.
- barrkel 9y agoYour philosophy of error handling composes poorly :)
- deleted 9y ago[deleted]
- rictic 9y ago> I also don't see why the unhandled exception from the background thread cannot terminate main thread. Why not? That is how unhandled exceptions are supposed to work. Terminating the program is the optimal default behaviour for any error in my opinion. This way you won't miss them. This is how unhandled promise rejections will be handled in node soon. In the browser, you can declare an event handler for unhandled promise rejections.
- fiatjaf 9y agoIn Go there are two ways you can handle wrong things happening: - return an error - panic What is the recommended, best, pretty, beautiful way? Return an error. Nobody uses panic. Javascript Promises are equivalent to that. If you want to stop the main program, call process.exit(). That would be the equivalent of panic.
- codedokode 9y agoI don't think it is beautiful. This fills program with lots of unnecessary `if`s for checking results of each call. Also, it prevents one from chaining functions like a(b(x)).
- fiatjaf 9y agoYeah, you're right. Not beautiful and prevents chaining. But works like a charm, don't you think? Chaining functions is for functional people. Go is proudly imperative.
- codedokode 9y agoIf you want to have a specific point to catch an exception, you could write something like this: def start_task(): thread = Thread(do_task) thread.set_error_handler(SpecificErrorType, handler) thread.start()
- rictic 9y agoYes, but this has a natural analogue in promise land: function startTask() { const promise = doTask(); promise.catch((e) => { if (e instanceof SpecificErrorType) { handler(e); } else { throw e; } }); }
- codedokode 9y agoThe difference is the default behaviour: whether errors are fatal or whether they are ignored by default.
- tonyg 9y agoErlang's links http://erlang.org/doc/reference_manual/processes.html#id88612 http://erlang.org/doc/reference_manual/processes.html#id8861... are an interesting approach to this problem of failure signalling in a concurrent system. Stack-oriented exception handlers certainly don't work properly with concurrency. Two Erlang processes (~actors) can be linked together. If one then crashes (uncaught exception), the other one is automatically killed - unless it takes special steps to "trap exits", in which case it is sent a message describing the failure in its linked peer.