Unity: Can we move away from silently failing APIs please?

Encountered another issue today that cost me about 3 hours simply because a unity API was silently failing. This time it was JsonUtility.ToJson(). If it fails to encode data it just silently returns the string "{}".

A few days ago it was Resources.Load. I also recall a time when the unity serializer would simply return null if it went more than 7 levels deep giving up assuming that it’s encountered a cyclic reference even if it hasn’t (that was fun when trying to cache KD trees of my static level into a scriptable object). At least that now logs a warning to the console although it didn’t always, I think it was added after I complained about it way back in the Unity 4.x days, but it’s still basically a silent fail when it should be an exception.

I’d really like Unity’s API developers to move towards a standard for properly handling exceptional program states. I understand that classical c# exception handling might be too heavy handed for a game engine but perhaps a light weight struct based error API would be a good alternative - object creation overhead for error systems is really only an issue when a program gets into an exception state. This is ideally something that never happens in a shipped build, but during production, error information is vital to diagnosing problems and maintaining development velocity.

Unity’s API surface is very large nowadays, which means the API landscape we (your customers) have to navigate is also vast and navigating it without proper error states can slow things down considerably.

For example, most resource loading (runtime and editor) has no error handling. It silently returns null when it fails. If you returned an error object showing the fully qualified path(s) that were searched most developers would be able to fix issues on the spot without consulting the documentation and future issues with malformed input would be caught sooner and cost less time to fix. I can’t be the only developer that’s had to read those same documentation for resource loading, editor loading, asset database etc about a dozen times because it’s never clear through actually using the code how they are intended to function, it’s just a black box API you toss a relative path into and pray you get something back.

I’m surprised you didn’t know about JsonUtility silently failing considering @Kurt-Dekker posts his copy about it at least once a week. I’m sure most folks here would reccommend using a more robust serialiser as well.

Can’t comment much about Resources. Never used it; went straight into Addressables, which does give you plenty of clear errors should something not be able to be loaded.

1 Like

JsonUtility wasn’t my choice, a 3rd party SDK I had to integrate was using it - so even if you can code around these issues in your own code, their existence in Unity’s public API means you still need to be aware of them. Resources API and things like it are unavoidable if you do any editor tools that need to use assets.

Regardless of all that, no one should have to work around any API because it’s implementation is poor. Fix it, or if they’re not going to fix it, deprecate if there’s a better alternative.

Even if it were to throw an exception. It wouldn’t matter when you still have an invalid json.
You’d still have to work your way around it. Sure you’ll get notified in the console if something is wrong. But you can do the same with Assertions. “Is my Data how I expect it to be?”

There is nothing to fix here really. The JsonUtility is a lightweight version. Yes it is missing features, but it can do its job if you have the proper class setup for it. I wouldn’t say it is poorly implemented, but rather too lightweight for a lot of usecases.
Personally I wouldn’t advise using it, but in a situation like yours you’re bound to use it. Like any third party SDK, it takes time and effort to implement.

As for Resources.Load even Unity tells you not to use it. You can still use it if you need it. Though as @spiney199 already mentioned, Addressables. Way better for loading assets.
For editor asset loading you can always use AssetDatabase API.

2 Likes

Disagree 1000%. These are just a few examples, there are many more similar issues throughout the unity API.

Honestly can’t believe I’m being told to write assertions to catch non-error output when an API fails or does something literally exceptional. Is in the name, exception. Also telling people they should have knowledge of other forums posts is insane. If it’s important info it should be in the documentation.

Not going to get into the mess that is addressables and no, the asset database does not cover the same functionality as resources like APIs on the editor side.

Perhaps the post is a little strong but Unity no longer has a feedback site and instead sends people here. Please learn to be ok with others wanting to hold unity to a higher engineering standard. If feedback is not welcome here then we need a better place for it.

Yes assertions because you just assume things are going to work the way you’ve structured your data. While your structure is incompatible with the JsonUtility class. You know your own data, what should be serialized and what not. Unity can’t know unless you actually tell it to serialize it. If you don’t then that’s on you, not on the JsonUtility tool.
It didn’t technically fail serializing the object you’ve thrown at it. It just didn’t find anything to serialize, because you didn’t mark it. Or the data was just incompatible to start with because it is a lightweight utility.
The utility still did its job though. It serialized the object into a Json object. But nothing else was found to serialize.

Addressables is not a “mess”. It’s a way of loading assets at runtime. Doesn’t matter whether it is on a server, local server or even streaming assets. You give it a reference and the API knows what you want to load.
It’s better than writing your own AssetBundle manager.
Also better than Resources.Load because anything in the Resources folder is loaded at the start of the application. Any large models or textures in there. All loaded into memory, all the time. With addressables things at least get unloaded when nothing uses it anymore.

I don’t see why not. It can load the asset from your project. It requires a more specific path or a GUID. That or you can filter using FindAssets. Personally I just go with asset GUIDs and use AssetDatabase.GUIDToAssetPath in combination with AssetDatabase.LoadAssetAtPath
Should there be an AssetDatabase.LoadAssetByGUID? I’d definitely vote for it. Does it make the API terrible? no, just inconvenient.

It sounds more like a rant than actual feedback IMO.

Unity has a roadmap at which you can suggest things. https://unity.com/roadmap/unity-platform
But if anything comes to a discussion then yeah the forum would be the place.

I agree that Unity should ship with quality. It’s not that feedback isn’t welcome. You have people with different opinions.
Opinions that clash with yours. As you disagree with me for an over exaggerating 1000%, I disagree with yours.

1 Like