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

Possible fix for #5032: Don't hang forever on asset loading error #5033

Merged
merged 14 commits into from
Dec 6, 2022

Conversation

diarmidmackenzie
Copy link
Contributor

Description:

Currently, if a bad URL is specified for an asset, A-Frame just shows the loading screen indefinitely (regardless of the asset timeout configured).

This prevents applications from providing application-specific handling (e.g. their own error message) when this might happen.
(in terms of why this might happen, suppose the HTML content is generated by server-side rendering on a back-end, and a bug emerges in the backend).

Changes proposed:

Update a-node processing when awaiting all children loading, so that:

  • it acknowledges the possibility of errors, and handles them
  • goes ahead and declares items "loaded" so that the scene can render, even if there have been errors.

I also added a small example showing the problem:
/examples/test/gltf-model-error/

Not sure if you'll want this included as part of the PR, but it was handy for reproducing the problem & validating the fix.

// Failed to load a node, but things won't get any better by waiting around.
// So get on with rendering the scene by signaling that this node has loaded.
// An "error" event has already been fired, so we don't need to fire another one.
warn('Rendering scene with errors on node: ', self);
Copy link
Member

@dmarcos dmarcos Mar 23, 2022

Choose a reason for hiding this comment

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

Don't you think this can be misleading? Worried that we're masking errors that the dev might want to stop and fix and could go unnoticed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There's already a console error about the failure to load a file.
So it didn't seem to me like another error was helpful, and a warning was the appropriate error level here.

Is there anything we can do apart from console warnings & errors to draw a Dev's attention to the fact that something is not right?

(apart from failing to render the scene at all, which as per #5032 I don't think that's a good solution).

<head>
<meta charset="utf-8">
<title>glTF Model</title>
<meta name="description" content="glTF Model - A-Frame">
Copy link
Member

Choose a reason for hiding this comment

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

I know it's misleading the test examples are not actually tests but simple examples that test very specific features. For this we should probably write a unit test

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK - I will have a go at a Unit Test.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Unit Tests now added.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can we leave this in as well, or do you prefer me to delete it?

Copy link
Member

Choose a reason for hiding this comment

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

I would remove this so examples/test is consistent. It serves the purpose to test visually specific features. Your unit test handles the failure case.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK - removed it.

@diarmidmackenzie
Copy link
Contributor Author

diarmidmackenzie commented May 3, 2022

Sorry for the slow progress on this.

I've now added some test cases.

It took me a long time to realize that Mocha is very sensitive to detecting unhandled errors, and will fail tests whenever your code emits an event named "error", and your test script does not immediately call done(), or stop event propagation.

The error message for this is rather opaque...

Error: [object CustomEvent] (undefined:undefined)

I have also adjusted the fix itself. Previously, as soon as a single faulty asset was found, it would jump into the scene. Now it proceeds with the rest of asset loading on the normal pattern, and logs warnings about the failed assets at the end.

I think that's better behaviour: as per the original issue, we want to mitigate the impact of one incorrect asset URL, but that doesn't mean we want to jump into rendering the scene before other, available, assets have had a chance to load.

@diarmidmackenzie
Copy link
Contributor Author

diarmidmackenzie commented May 3, 2022

I've left the gltf_model_error.html test file in for now, as I found it pretty useful while working on this, so it could be useful in future?

But happy to remove it if you prefer...

src/core/a-node.js Outdated Show resolved Hide resolved
src/core/a-node.js Outdated Show resolved Hide resolved
@diarmidmackenzie
Copy link
Contributor Author

@dmarcos, with the UTs done, can this be merged now? Or are there other concerns to address?

@kylebakerio has reached out to ask whether I can push ahead and get this merged.

@vincentfretin
Copy link
Contributor

@dmarcos you should probably merge this first, then I will rebase #5123 to resolve a conflict.

@vincentfretin
Copy link
Contributor

@diarmidmackenzie can you please rebase your PR, you need to fix the conflict around evt.stopPropagation(); since #5123 was merged first.

@diarmidmackenzie
Copy link
Contributor Author

@diarmidmackenzie can you please rebase your PR, you need to fix the conflict around evt.stopPropagation(); since #5123 was merged first.

Done.

@dmarcos
Copy link
Member

dmarcos commented Nov 17, 2022

This needs a rebase. Combing through open stuff to prep for a 1.4.0 release. Thanks for the patience

@diarmidmackenzie
Copy link
Contributor Author

diarmidmackenzie commented Nov 18, 2022

I believe this is now all up-to-date with latest master again.

A couple of conversation points where I'm not 100% sure whether you were happy with what I'd proposed or not..
#5033 (comment)
#5033 (comment)

@diarmidmackenzie
Copy link
Contributor Author

Hmm - seing a test failure like this:
SUMMARY:
✔ 734 tests completed
ℹ 3 tests skipped
✖ 1 test failed

FAILED TESTS:
✖ "after each" hook for "does not try to enter VR if already in VR"

I'll look into it.

@diarmidmackenzie
Copy link
Contributor Author

OK, I don't know why this test issue has only come to light now, but it is due to inadequate mocking of the canvas element.

This leads to an exception in the look-controls component when it tries to add to the canvas classList.

TypeError: Cannot read properties of undefined (reading 'add')
      at enableGrabCursor (build/commons.js:17060:32)
      at NewComponent.updateGrabCursor (build/commons.js:17074:7)
      at NewComponent.update (build/commons.js:16723:12)
      at NewComponent.initComponent (build/commons.js:26161:10)
      at NewComponent.updateProperties (build/commons.js:26130:12)
      at AEntity.updateComponent (build/commons.js:24971:17)
      at AEntity.updateComponents (build/commons.js:24948:12)
      at entityLoadCallback (build/commons.js:24739:12)
      at emitLoaded (build/commons.js:25673:9)

I believe the solution (which I've just added as a fix into this PR) is to extend the mock canvas object so that classList.add and classList.remove can be invoked without causing exceptions.

I don't have a good understanding of why this didn't cause problems prior to this fix, but the exception does occur in a loading callback, and we have made changes in the handling of such exceptions, so it's plausible that for some reason this exception didn't cause problems for the tests previously.

This particular failng test is not intended to test exceptions, and the intent of the test will be better met if we avoid these exceptions, which is what the extension to the canvas mock object achieves. So I think that is the correct fix, and I don't see any evidence of a problem in the code under test.

@kylebakerio
Copy link
Contributor

Vincent has made many changes asnd improvements to the tests in recent months, part of which allowed many tests that were being skipped to now be run. Could be related to that, I didn't look into those changes in too much detail.

Good catch and fix.

@vincentfretin
Copy link
Contributor

There is also an error on master with firefox related to classList that is not mocked properly
https://github.com/aframevr/aframe/actions/runs/3520429062/jobs/5901336232
I don't know either why it shows up only now. It may be good to create a PR just for this mocking fix if this PR is not merged right away.

@vincentfretin
Copy link
Contributor

I created #5176 with a slightly modified version of the fix @diarmidmackenzie

@diarmidmackenzie
Copy link
Contributor Author

@dmarcos Do you want to take this fix? Or give more feedback on the discussion items above?

classList: {
add: function () {},
remove: function () {}
},
Copy link
Contributor

Choose a reason for hiding this comment

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

@diarmidmackenzie now that #5176 is merged, you should remove first those 4 lines and then merge changes from master to fix the conflict.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Of course - sorry, didn't immediately register the implications of your comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Those updates are done.

@dmarcos
Copy link
Member

dmarcos commented Dec 6, 2022

We can merge this once we remove the example. Thanks for sticking with it.

@diarmidmackenzie
Copy link
Contributor Author

Ok - removed that file from examples\test so I think we're good now.

@dmarcos
Copy link
Member

dmarcos commented Dec 6, 2022

Thanks so much. Super appreciated

@dmarcos dmarcos merged commit 5189765 into aframevr:master Dec 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants