I try to understand what's the best way to handle error conditions in Unity. In a lot of places I've read that throwing exceptions is a bad thing. Unfortunately, I have not found any guidance on Unity website on this matter as well finding clear guidance on the wide Internet is also difficult.
What I use quite often is Debug.Assert
statements to check that certain conditions for proper operation are met.
But what to do, if something unexpected happens? Some examples could be:
- Network connection lost
- File write operation failed (for some reason)
What is a good practice to handle these situations? Just do a Debug.LogError
to log important info and then let the game crash?
Happy to hear your thoughts on this.
Thanks!
Update 12.08.2019 22:06
Based on the comments received, I have added the code example below with some comments / thoughts from my side.
Example: Load Level Data From JSON File
In this example, I load level data from a JSON file (SceneData.json). It could theoretically happen, that the level file is not available. I do not check the result of Resources.Load()
yet, but if the file cannot be found, a NullReferenceException
is thrown. I have not tested this yet, but I think a NullReferenceException
will terminate the whole Unity game at runtime. So how to improve this situation in a way, that informs the player about this problem? What can be done to support the developer in fixing the issue?
Some thoughts from my side for improving code:
- I should check the return value of
Resources.Load()
. If it isnull
, I also issue aDebug.Error
log. That way, the problem gets logged to the console during testing/development but also to thePlayer.log
on the target system (e.g: Windows). - If I want to inform the player about the problem, I could return
null
in theGetDragAndDropLevel
method to inform the caller about the fact, that no level was loaded. I could the further propagate this information up the call stack to display an error message in the GUI at the end.
Does this sound reasonable in the Unity context? Or do you guys do this stuff completely different?
public static DragAndDropLevel GetDragAndDropLevel(GameLanguage language, GameScene scene, int level)
{
Debug.Assert(level >= 1);
// Generate filename
var sceneDataFilename = "SceneData/" + scene + "/SceneData";
// Read JSON structure into SceneDataDragAndDropLevel object
var textAsset = Resources.Load<TextAsset>(sceneDataFilename);
var jsonData = textAsset.text;
Logger.LogDebug(jsonData);
var sceneData = JsonConvert.DeserializeObject<SceneData>(jsonData);
var numLevels = GetNumberOfLevels(sceneData, GameType.DragAndDrop, scene);
Debug.Assert(level <= numLevels);
// Generate level object
var dragAndDropLevel = GetDragAndDropLevelFromSceneData(sceneData, level);
return dragAndDropLevel;
}