Error Handler

Usually in game development, we want each error to be detected immediately and processed gracefully. Recently I am working on error handler to handle all different error states in our game. Here I would like to talk about it in detailed.

To begin with, it should be clear that error detection and error process should be separated. In language like C++ and Java, they use try-catch to handle the error. But using try-catch might not be always a good idea. Joel Spolsky pointed out two drawbacks of using try-catch.

  1. They are invisible in the source code. Looking at a block of code, including functions which may or may not throw exceptions, there is no way to see which exceptions might be thrown and from where. This means that even careful code inspection doesn’t reveal potential bugs.
  2. They create too many possible exit points for a function. To write correct code, you really have to think about every possible code path through your function. Every time you call a function that can raise an exception and don’t catch it on the spot, you create opportunities for surprise bugs caused by functions that terminated abruptly, leaving data in an inconsistent state, or other code paths that you didn’t think about.

Moreover, for me, I would like to have my own error message data structure. Therefore, rather than use try-catch directly, I create my own error handler class. The general idea of this class is still similar to try-catch, it has two main functionality, which are error detection and error handle.

Here is the workflow when an error occurs:

  1. One error occurs
  2. All listeners handle this error event. If the error is solved, clear the error.
  3. Check whether error still exist
  4. If yes, bing player back to the first scene
  5. Show error message to player (UI pop up)
  6. Player could check whether error is solved by pressing error message UI button.

Back to my ErrorHandler class, it has following things:

Function

  • void ErrorStateReport();                                             //Call back function when an error is detected
  • bool CheckErrorState( ErrorType i_error);            //Check one certain type of error whether exists.
  • bool CheckError();                                                       //Check whether there is still an error
  • void ClearError();                                                        //Clear error, set errorType to None.
  • void SetError( ErrorType i_error);                         // Set errorType to a certain type of error.

Data Member

  • readonly Dictionary<ErrorType, string> ErrorMessageDictionary;                // Store display information for each error type
  • ErrorType ErrorType;                                                                                                 //Error type.
  • delegate void OnErrorState( string errorMessage, ErrorType errorType);     //Error delegate
  • event OnErrorStateEvent OnErrorState;                                                                //Error event

Here is the workflow by using ErrorHandler class:

Scene where error occurs

  • //Error occurs
  • ErrorHandler.ErrorStateReport( Error );                                                       //All listener would handle the error
  • if(ErrorClientHandler.CheckError()) ErrorClientHandler.ErrorType = // one error type
  • //Back to first scene

First scene

  • if(ErrorClientHandler.CheckError())  ShowErrorUI( ErrorClientHandler.ErrorMessageDictionary[ ErrorClientHandler.ErrorType], ErrorClientHandler.ErrorType);
  • //….we are in error state now
  • //If player press error message UI button
  • if( !ErrorClientHandler.CheckErrorState(ErrorClientHandler.ErrorType) ) //error solved
  • //Keep retrying, error still exists.

This is ErrorHandler class I create. And it could match the requirement of our game’s error handle perfectly.

 

New Update

I have to say game reset is also a very dangerous activity. It is ironic that when I tried to use error handler to reset the game, it would bring new errors and crash the whole game.

This is what resetGame function did before:

  • Uninit the game;
  • Game back to main menu scene;

But when game uninited itself, some monobehaviour scripts were still running, and they might want to have the access to game data. Unfortunately, game data just destroyed itself. Then new error (null exception) came out, and at last game crashed.

The solution to this problem is before uniniting the game data, make game first enter an empty game scene to ensure no object still has reference to game data. Then we uninit game data, and last bring player back to main menu scene. So the new workflow turns out to be:

  • Go to empty scene;
  • Uninit the game;
  • Game back to main menu scene;

Exceptions

Exceptions DoSomething()

Exceptions vs. status returns

About Jinghui Dong

An engineer student from Cohort4 class in EAE program in University of Utah. Be passionate about the game development, game design, and still interested in art.
Bookmark the permalink.

Leave a Reply