Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[api-minor] Ensure that the getDocument Promise is rejected if the loadingTask is destroyed, or an Error is thrown, inside of the onPassword callback (issue 7806) #7926

Merged
merged 2 commits into from
Jan 4, 2017

Conversation

Snuffleupagus
Copy link
Collaborator

@Snuffleupagus Snuffleupagus commented Jan 2, 2017

Tentatively fixes #7806 (and replaces PR #7924).


This change is Reviewable

Copy link
Contributor

@yurydelendik yurydelendik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It getting really complicated, thanks for working on this issue.

@@ -1435,6 +1436,13 @@ var WorkerTransport = (function WorkerTransportClosure() {
this.destroyed = true;
this.destroyCapability = createPromiseCapability();

if (this._passwordCapability) {
var err = new Error('Worker was destroyed during onPassword callback');
this.loadingTask._capability.reject(err);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking we can avoid doing that: the loading task canceling shall be coming from worker side.

Copy link
Collaborator Author

@Snuffleupagus Snuffleupagus Jan 2, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is definitely getting more complicated than I imagined; thanks for your in-depth review comments thus far!

I tried removing that, but it appears to be causing some problems:
When calling loadingTask.destroy(); in the onPassword handler, it seems that the worker is terminated before it has had a chance to send the (new) PasswordException (as outlined in comment https://github.com/mozilla/pdf.js/pull/7926/files#r94335620).

The loadingTask will thus remain in a pending state, without ever getting either resolved or rejected. Note that I'm seeing this both in manual tests in the viewer, as well as in the unit-tests.

EDIT: For now, I removed this and use a WorkerTask to ensure that we wait (in worker.js) for the _passwordCapability from api.js. How would you prefer that we handle this case?

try {
loadingTask.onPassword(updatePassword, exception.code);
return this._passwordCapability.promise;
} catch (ex) { }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are properly handling exception at sendWithPromise, so we can avoid doing error capture here.

var error = new PasswordException(exception.message, exception.code);
loadingTask._capability.reject(error);

this._passwordCapability.reject(error);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you check for !loadingTask.onPassword and returned rejected promise (with PasswordException).

}, this);


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: remove unneeded line

}
handler.sendWithPromise('Password', e).then(function (data) {
pdfManager.updatePassword(data.password);
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add .catch(function (e) { handler.send('PasswordException', e); });. (I'm not sure if we need to re-wrap e, but I think this will work out) We need to add 'PasswordException' handler, to abort loading task. Password can be PasswordRequest to avoid confusion.

Copy link
Contributor

@yurydelendik yurydelendik Jan 2, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code at pdfManagerReady below looks non-symmetrical to recovery password handling. I think we shall remove pdfManager.passwordChanged/._passwordChangedCapability? The pdfManagerReady will be called after password update (we need to move pdfManagerReady from being anonymous function to closure before getPdfManager() call).

Copy link
Collaborator Author

@Snuffleupagus Snuffleupagus Jan 3, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add .catch(function (e) { handler.send('PasswordException', e); });. (I'm not sure if we need to re-wrap e, but I think this will work out)

A complication with this is that the exception we catch here is actually a string (it's converted by the MessageManager), rather than the expected Error here since postMessage has issues with serializing those.

EDIT: For now, the patch is still sending the original PasswordException in this case, since I'm having trouble getting the rejection of the loadingTask to work properly otherwise.

@Snuffleupagus
Copy link
Collaborator Author

Snuffleupagus commented Jan 3, 2017

@yurydelendik Thanks for the in-depth review comments! I've tried to address them, but there's a couple of things I'm not entirely sure how to handle, please see #7926 (comment) and #7926 (comment).

Copy link
Contributor

@yurydelendik yurydelendik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. From the comments above I did not get if there are any issues, but that's what I had in mind (except WorkerTask, but it's okay to have it). Thank you for the patch.

…`loadingTask` is destroyed, or an `Error` is thrown, inside of the `onPassword` callback (issue 7806)

This patch also removes the `UpdatePassword` message, in favour of using the `sendWithPromise` method of `MessageHandler`.
Furthermore, the patch also refactors the `BasePdfManager_updatePassword`/`BasePdfManager_passwordChanged` methods (in pdf_manager.js), and the `pdfManagerReady` function (in worker.js).
…er`s, instead of in the `XRef`

We're already passing in a, currently unused, `PdfManager` instance when initializing the `XRef`. To avoid having to pass a single `password` parameter around, we could thus simply get the `password` through the `PdfManager` instance instead.
@Snuffleupagus
Copy link
Collaborator Author

/botio test

@pdfjsbot
Copy link

pdfjsbot commented Jan 3, 2017

From: Bot.io (Windows)


Received

Command cmd_test from @Snuffleupagus received. Current queue size: 0

Live output at: http://107.22.172.223:8877/66a013cc55d0e54/output.txt

@pdfjsbot
Copy link

pdfjsbot commented Jan 3, 2017

From: Bot.io (Linux)


Received

Command cmd_test from @Snuffleupagus received. Current queue size: 0

Live output at: http://107.21.233.14:8877/70ebc3f297bfa0d/output.txt

@pdfjsbot
Copy link

pdfjsbot commented Jan 3, 2017

From: Bot.io (Windows)


Failed

Full output at http://107.22.172.223:8877/66a013cc55d0e54/output.txt

Total script time: 25.99 mins

  • Font tests: Passed
  • Unit tests: Passed
  • Regression tests: FAILED

Image differences available at: http://107.22.172.223:8877/66a013cc55d0e54/reftest-analyzer.html#web=eq.log

@pdfjsbot
Copy link

pdfjsbot commented Jan 3, 2017

From: Bot.io (Linux)


Success

Full output at http://107.21.233.14:8877/70ebc3f297bfa0d/output.txt

Total script time: 26.82 mins

  • Font tests: Passed
  • Unit tests: Passed
  • Regression tests: Passed

@Snuffleupagus
Copy link
Collaborator Author

/botio-windows test

@pdfjsbot
Copy link

pdfjsbot commented Jan 3, 2017

From: Bot.io (Windows)


Received

Command cmd_test from @Snuffleupagus received. Current queue size: 0

Live output at: http://107.22.172.223:8877/20d27329fbde995/output.txt

@pdfjsbot
Copy link

pdfjsbot commented Jan 3, 2017

From: Bot.io (Windows)


Success

Full output at http://107.22.172.223:8877/20d27329fbde995/output.txt

Total script time: 25.71 mins

  • Font tests: Passed
  • Unit tests: Passed
  • Regression tests: Passed

@Snuffleupagus Snuffleupagus merged commit aabfb77 into mozilla:master Jan 4, 2017
@Snuffleupagus Snuffleupagus deleted the api-onPassword-abort/throw-Promise branch January 4, 2017 09:48
movsb pushed a commit to movsb/pdf.js that referenced this pull request Jul 14, 2018
…rt/throw-Promise

[api-minor] Ensure that the `getDocument` Promise is rejected if the `loadingTask` is destroyed, or an `Error` is thrown, inside of the `onPassword` callback (issue 7806)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Handle loading abort/failure in password callback
3 participants