How to implement a moldable exception
Overview
The basic steps are the following:
(1) Define a new subclass of Exception
that encapsulates all the data you need your dubugger views.
(2) Add view methods to your exception class with a <gtExceptionView>
pragma.
(3) Catch exceptions when they occur, and signal instead your new exception.
Example — Moldable Ludo exceptions
Let's look an example where we want to catch errors in playing a GtLudoRecordingGame
.
The game already makes use of assertions to detect errors in the game play:
#assert:description: gtSenders & GtLudoMove gtMethodsInClass.
We define our own exception LudoMoveAssertionFailure
which encapsulates the problematic move, and we signal it in GtLudoMove>>#assert:description:
, which now overrides Object>>#assert:description:
.
We just add a few simple, forwarding debugger views, namely:
LudoMoveAssertionFailure>>#gtGameViewFor:
, and
LudoMoveAssertionFailure>>#gtMovesViewFor:
Each of these views forwards to a view we already have for the Ludo game.
Now we can see the moldable exception in action by provoking exceptions.
Here we try to move without rolling the die first:
GtLudoRecordingGameExamples new bEntersAndPlaysWithAahead moveTokenNamed: 'B'; yourself.
Here we try to move the wrong player:
GtLudoRecordingGameExamples new bEntersAndPlaysWithAahead roll: 6; moveTokenNamed: 'B'; yourself.
In both cases we now get a Debugger with our three debugging views. We can switch back to the regular debugger by clicking the GT Debugger
button at the top.