Handle runtime errors when loading tilesets

Is there way to correctly handle such errors?

error

This error occurs when im trying to load tileset from url:

try {
  tileset = await Cesium3DTileset.fromUrl(tilesetUrl, {
     show: true,
     dynamicScreenSpaceError: true,
     maximumScreenSpaceError: 2,
   });

  ...

catch (err) {

  ...

}

It doesnt throws any error that could be caught in a catch block, just message in console.

I can use allTilesLoaded Event, but that’s not quite what i need

Hi @messenja, have you tried using the tileFailed event?

Yes, but this callback not called for that error. I think such error should pops up in the catch block in my code, but it does not

Hi @messenja ,

Did you verify the 3DTileset is valid? You can use GitHub - CesiumGS/3d-tiles-validator: Validator for 3D Tiles 🚦 to check.

If it is valid, I think the next step would be for us to look at the tileset if you can provide it, so we can investigate.

Thanks,

Luke

Hi Luke, no, it has errors.

...
{
  "_type": "CONTENT_VALIDATION_ERROR",
  "_path": "/bufferViews/3/byteStride",
  "_message": "Value 2 is out of range.",
  "_severity": "ERROR",
  "_causes": []
},
...

and i want to correctly hanlde this

Hi @messenja,
Thanks for confirming the validator output. Next questions/steps:

  • How did you generate your tiles? Did you use Cesium ion?
  • Are you able to share your tileset and source data? This will allow us to investigate and debug locally. If you prefer not to post here, you can send a direct message to me.

Hope we can narrow down this issue soon.
Thanks,
Luke

I think the question is more about error handling, and not so much trying to fix this particular example. In an ideal scenario, it should be as simple as Cesium throwing an exception, with clearly defined warnings and true errors.

I’ve encountered similar situations where Cesium spits out errors in the console.log, however I can’t catch the error to handle things differently further up the stack in my (by now) rather complex code. An example is when you try to pick outside the globe, it doesn’t throw an error (or warning), but returns an undefined. Now, of course I can check on that and throw my own errors which can trickle up through various try/catch sections, and I do indeed spend a lot of code and time trying test and throw errors/warnings where applicable. I’m putting this one down as a plea towards a more modern way of dealing with various warning and error conditions. (Another one would be more events for various things happening in the engine, as well, but that’s a different post … :slight_smile: )

Hi @Alexander_Johannesen ,

Thanks for clarifying your question is more about error handling. Your point is well taken about the benefits of throwing true errors rather than the type of runtime error you encountered. I do think it is our intention to throw errors in the situation you encountered, so if you are willing to submit an issue in the Cesium repo we would certain investigate. If you make the issue please include sample data along with your code so we can reproduce it and test a potential solution.

Separately and more broadly in the context of 3DTiles, I’ve seen applications using CesiumJS that will import 3d-tiles-validator as a dependency, then check tilesets before attempting to load them in CesiumJS. While I cannot find any old GitHub discussion to point to, my hunch is that the the validator is separate from CesiumJS because validating needs to happen in other contexts besides loading and rendering, like after tileset creation.

Thanks,
Luke

Hi Luke,

Yeah, possibly, but not every app or every infrastructure can fit the validator in easily. But also, it may not be the whole tileset that’s wrong, just bits of it. Cesium is good at dealing with some of that, say tiles at a certainly zoom level is corrupt, then it means there’s a visual element to debugging that works for users but not for a validator. :slight_smile: Anyway, throwing exceptions is nice practice.

Cheers,

Alex

I agree with the broader requirement of improved error handling.

About the validation: The 3d-tiles-validator is error checks. That sounds wrong :slight_smile: But it is (literally) a collection of error checks. Namely, all the checks that the runtime engine should not have to do. I think that its primary use is in authoring pipelines and tilers: It shoud/could be used to regularly validate that the tilesets that are generated by some tool are actually valid.

I’d hesitate to apply it to each tileset before loading it in a runtime engine. Depending on the size of the tileset (and e.g. the number of warnings that are generated for the glTFs), this can be slow, and the resulting report can be huge.

(And one step further: At the runtime engine, it’s too late. The validator might report an error, but there’s nothing that the (“consuming”) end-user can do about that)

Now, even though the runtime engine should not (have to) do these low-level, nitty-gritty checks, one still has to anticipate certain errors, to some extent. There are some functions for dealing with the nasty “Rendering has stopped”-category of errors (although that also has room for improvement). But I think that for loading (tile data), there is not much. We might have to investigate this particular error. Intuitively, I’d expect an “invalid glTF model” to end up as a tileFailed-event. This might, very pragmatically, just be a matter of wrapping some try ... catch (...) { tileFiled.raise(); } around the model loading function.

(In doubt, I’ll check if there’s already an issue for that, and maybe open one, with example data…)

Thanks Marco,

All good points. Is the codebase of the “validator” so large it couldn’t be part of cesium proper? Or does it use tech that’s non-browser? (I did a quick scan, but don’t know it intimately) I also think people might struggle with the non-maintained status (unless that’s changed in recent years, or maybe I’m thinking of an older repo?) I’m guessing there’s some history that explains its nature and state, maybe a tiny bit of time cleaning up those concerns might help? In fact, throw in a good sprinkle of exceptions and / or events and / or hooks, it could be quite a useful and much loved framework. Don’t know, would be happy to help.

Cheers,

Alex

The 3D Tiles Validator is still actively maintained!


For the case that someone is curious about the “history” of the 3D Tiles Validator (this is only a very rough summary):

Once upon a time, there was a 3d-tiles-validator repository. This was later renamed to 3d-tiles-tools, combining the “validator” and general “tools”. Later, this was extended with the “Samples Generator” functionality (that us used for generating some of the CesiumJS spec data). Then the whole project was dormant for a while (this is what you might refer to with the “non-maintained status”).

But ~3 years ago, I picked up the the work here. I revived the core of the 3d-tiles-tools project, which was largely a rewrite of the existing functionality with more modern TypeScript. The validation part was essentially rewritten and put into the dedicated 3d-tiles-validator repo. (Yes, this repo already existed, before it was renamed to 3d-tiles-tools … some back and forth here :slight_smile: ). The 3d-tiles-validator now uses the 3d-tiles-tools as a dependency.
(The “Samples Generator” was also extracted into a 3d-tiles-samples-generator repo, but this one is indeed unmaintained right now)


Back to the more specific points:

A bit of both, and more.

  • The validator itself is not tremendously large.

  • But: The validator depends on the 3d-tiles-tools, which is a bit larger, and could raise the question of which parts of this should ~“also be part of CesiumJS”. This may be obsolete due to the following points…

  • Both the validator and the tools are using TypeScript, so they can not directly be part of CesiumJS anyhow.
    (I’ve been swearing quite a bit about that CommonJS/AMD/UMD/ESM/ES20XY stuff. They really messed that up)

  • Both the tools and the validator use some structures that are non-browser, but I tried to keep the scope of that narrow.
    (There is some pragmatic ResourceResolver interface that is supposed to be an abstraction of either file or network resource access - so it is largely “prepared” for separating out the NodeJS/file-specific parts, but right now, the file-specific parts are still part of the package itself. There are some “legacy” parts, related to 3TZ validation, that are hard-wired to use files, but that could be carved out with reasonable effort - 3TZ is not relevant for CesiumJS after all)

  • Maybe the most important point: I think that the scope and goals are ~“too different”

The last point refers to what I consider the primary use-cases:

The validator will usually be used to fully validate some 10GB/10000files tileset that was generated by some tiler. The validator fully traverses the whole tileset(!), and calls the ‘glTF-Validator’ for each content(!). This is usually slow, and of course, should definitely not be done in CesiumJS ~“before loading a tileset”. The whole idea of 3D Tiles, aiming at streaming data, will confront a runtime engine with this challenge: I’m downloading something right now. It might contain errors. I have to deal with that.

This comes back to the specific issue of the error handling in CesiumJS:

The error handling does not seem to be very consistent. I started some local tests, and there are some observations for now:

  • There are cases where an invalid GLB (one that is invalid according to the spec and the glTF-Validator!) is silently loaded and works. That’s … OK-ish, I guess. CesiumJS is trying to ~“make the best of it”, and succeeds (in this case)
  • There are cases where an invalid GLB/B3DM causes and error, and that error causes the tileFailed event to be triggered. That’s the right behavior. That’s what the tileFailed event is for.
  • There are cases where a valid GLB causes an error. I tried this out with the exact example that sparked this thread, namely an invalid sampler.wrapS mode. I recently opened Consider a fallback for invalid sampler wrap modes · Issue #12781 · CesiumGS/cesium · GitHub . This is an issue for itself
  • Regardless of whether that GLB is valid or not: This is one example of an error that does not trigger the tileFailed event. But it should trigger that. So that’s an independent issue.

Until now, my tests focussed on ~“invalid tile content”. One could probably come up with more test cases. And one could not only come up with them, I already did come up with them - for the validator specs :slight_smile: I usually did not try to load (all of) these files in CesiumJS. But it could be interesting to see how CesiumJS behaves in these cases (even though there certainly is an overlap to the CesiumJS specs).

In addition to “invalid content”, there are the “Rendering has stopped”-errors. Two years ago, I pointed that out, with a dummy example:

Cesium Render Error

I think that it would be nice if that rendering error could be caught more defensively, and handled like this:

But… that may be difficult: When there is an actual WebGL error, then the WebGL context may be irrecoverably “broken”, so this may not be applicable in all cases.

(Such a “Toast-Popup” could, however, still be nice even for handling tileFailed errors. Right now, the default is that it prints the error to the console (in most cases), and even when establishing a tileFailed handler, it’s not easy to inform the user about the error)

Thanks Marco for that very comprehensive reply, explains a lot. I do my work already in TS (front and back), so I might look to incorporate it directly. I can use it to create further exceptions directly, just got to figure it the API side of things.

The comment on it not being maintained was from a cesium rep in the forums, but quite many years ago, I’m happy to see that changed.

Again, thanks for all that, and I’ll keep you posted on a TS integration later that might be useful for others. And there’s always back compilation to JS as well to consider

Cheers,

Alex

Just a short heads-up: I noticed another error that bubbled up, with largely the same stack trace. Essentially, I think that the Model.update call can throw for a bazillion of reasons (bugs as well as invalid input data). So I opened Some runtime errors are not handled properly · Issue #12876 · CesiumGS/cesium · GitHub, maybe this can easily be handled.