-
Notifications
You must be signed in to change notification settings - Fork 520
continuation with bad Executor leads to un-predictable result and the Exception is hidden #106
Conversation
By analyzing the blame information on this pull request, we identified @bklimt, @grantland and @belemaire to be potential reviewers. |
Thank you for your pull request and welcome to our community. We require contributors to sign our Contributor License Agreement, and we don't seem to have you on file. In order for us to review and merge your code, please sign up at https://code.facebook.com/cla - and if you have received this in error or have any questions, please drop us a line at cla@fb.com. Thanks! |
Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Facebook open source project. Thanks! |
I'm not sure we'd want to pass a runtime exception from the executor to the next task in the list and a failure of that magnitude should cause the application to crash as you've seen. Is there any reason you'd want to be able to recover from a exception such as this where there was an error in your executor implementation? |
I agree that in most cases, failure on this scale should crash the app. The main problem was that Bolts hides the exception cause and on bigger project, it would takes a lot of effort to found the origin of the problem. Current implementation will only crashed the app with IllegalStateException("Cannot set the error on a completed task.") with stacktrace pointing to Bolts source, rather than the app source. And since most of my Bolts continuation ended with checking and logging for any fault found, that is the reason i put the exception into continuation. Anyway, I would propose that the exception hiding bug should be handle in different way, while decision for sending the exception to Task continuation or should be crashing the app, can be decided by your team. As my own preference, and usage pattern, i do want to recover from executor fault. In my project, I'm using android Handler for Executor implementation and i would like to have Task to fail gracefully without crashing when i shutdown the Handler looper :) |
Hrm actually I stand corrected, a bad Mind squashing your commits so I can merge? Thanks and sorry about that! |
Actually, we'd probably want this safety on |
@yunarta updated the pull request. |
@yunarta updated the pull request. |
I made fixes to Task.call(callable, executor) as well |
Could you also add tests for these as well? I can see we'd need ones for the following:
|
@yunarta updated the pull request. |
Hi Grant I added test for the requested three items. And i decided to remove ExecutorException, so developer can see the exception caused by their Bad Executor |
@yunarta updated the pull request. |
1 similar comment
@yunarta updated the pull request. |
Thanks for adding tests! I actually think think that we should keep |
I removed ExecutorException because when I'm using Bolts task chaining, I would throw in middle and catch it as i know what Exception being thrown back then. With ExecutorException, when someone purposely throw a specific exception subclass in Executor execute function, they would be perplexed when they found they get ExecutorException instead for the first time, and probably will contemplate why Bolts need to wrap the know exception in the first place. |
That works in the case where you own both the Executor and the continuations, but I don't think it does if you don't. For example, if you were using a prebuilt What do you think of this case? |
Let me test more cases |
I think you are right, it would be much better to emphasize that this error originating from Executor. |
@yunarta updated the pull request. |
/** | ||
* This is a wrapper class for emphasizing that task failed due to bad Executor, rather than the continuation block it self. | ||
* <p/> | ||
* Created by yunarta on 22/12/15. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you remove this? We don't record authorship on class JavaDocs, but through git blame/commit history.
…d the Exception is hidden * Executor execute function now wrapped with try-catch for errors coming from the Executor execute method
@yunarta updated the pull request. |
continuation with bad Executor leads to un-predictable result and the Exception is hidden
Thanks for you're awesome contribution! As a thank you, we'd like to send you some Parse swag. If you're interested, send me your mailing address and t-shirt size to my email address on my profile page. |
Nice to work with you as well Grant 👍 |
I'm using bolts heavily with Executor to synchronizes the continuation blocks.
When i made a mistake in the Executor implementation, causes a NullPointerException to be raised, i found that this would crash the app due to the exception was raised to the previous Task.
The snippets kind of like below
Since the BadExecutors throws NPE, rather then having the NPE being sent to to next continuation block, it crashes the app with IllegalStateException("Cannot set the error on a completed task.")
This is caused by the the Executor.execute is not wrapped by try-catch, causing the exception being sent back to finishing block of the previous task in the chain where the Task result being set as completed, continuations blocks is being executed