[Newbies] Changing error message

Ron Teitelbaum Ron at USMedRec.com
Thu Aug 3 16:00:36 UTC 2006


Hi Sedar,

Welcome to the list.  Before giving you and explanation let me say that if
there is anything I mention which you do not understand please feel free to
ask questions.

There are a few things to understand about exception handling.  First is
that there is a class called Exception.  Have a look at the hierarchy of the
class.  

There are two parts to exception handling.  There is the error itself, and
then there is the exception handler.  An error is signaled (sometimes called
raised).  The handler catches the error and handles it.

Notice in the hierarchy that there is a class Error.  This is usually where
you want to start for errors in code because if you wrote a handler for
Exception you would prevent errors, or handle errors yourself that you would
rather the system handle.  Things like halt are a good example.  

When an exception is signaled the system looks in the calling stack for a
handler.  A handler could that used the class of the exception or any of its
superclasses can handle the error.  For example if I have a:

Error subclass: #MyGeneralError

And

MyGeneralError subclass: #MyNoDigitError 

Then if the code does MyNoDigitError signal: 'You should have more then one
digit here.  Thank you'

Then if you have a handler for #MyNoDigitError or #MyGeneralError or both,
it will execute the handler for which ever one comes first in the stack.

Ok I'm glad you made it this far stick with me and then I'll give you an
example which should help to make it clear.

For a stack to have a handler the code that you are executing needs to have
an exception wrapper.  In other words you need to wrap the code that you
think might signal an error.  To wrap the code you put your code in a block
and then add the Error class and the handler.

[self myCode] on: MyNoDigitError do: [:ex | self myHandlerCode].

[A little aside.  You can skip this part if this is already too complicated.
What I like to do is code my handlers on my exception class so instead of
self myHandlerCode I use ex myHandlerCode.  The ex is an instance of your
error class so you can put code right on that class to do what you want.
Also you can use tag to add more information on your class like the
instances you need to operate on.  You can even add additional ivars to your
exception class to hold what ever you want.  The benefit of this is that all
your exception handlers are in one place so it's easy to find and reusable!]

Ok so examples:

First something that just works.  Create the classes above MyGeneralError
and MyNoDigitError

Notice that both of these work.

[MyNoDigitError signal] on: MyNoDigitError do: [Transcript cr; show: 'Hey I
hit an error'].

[MyNoDigitError signal] on: MyGeneralError do: [Transcript cr; show: 'Hey I
hit an error'].

Now it's time to use your imagination.  Because this is a very primitive
example you have to actually imagine using it.

Imagine a method.

ATMMachine >>depositAmount: anAmoutToDeposit
	"return to the sender aBoolen which represents the acceptance or
rejection of anAmountToDeposit.  When accepted the receiver will forward
anAmountToDeposit to the authenticated users selected bankAcount where it is
placed on hold until anAmountToDeposit is verified"

	self userIsAuthenticated ifFalse: [ATMLoginError signal: 'User has
not been authenticated'. ^false].
	self selectedBankAccount ifNil: [ATMNoSelectedBankAccount signal:
'Please select an account to deposit too.'. ^false].
	anAmountToDepost hasDigits ifFalse [^MyNoDigitError signal: 'I can
only deposit numbers'. ^false].
	self selectedBankAccount holdDepositForVerification:
anAmountToDeposit.
	^true

Ok well that handles the error signaling the error.  Now we need to wrap it.

ATMMachine >> deposit
	"request amount to deposit and perform depositAmount"
	
	anAmountToDeposit := self getAmountFromUser: 'How much did ya want
to deposit?'.
	[self depositAmount: anAmountToDeposit] on: ATMLoginError,
AtMNoSelectedBankAccount, MyNoDigitError do: [:ex | self
cutUpUsersAtmCardAndBlowRasberriesAtThem].

So now you can see that if the user does something wrong we handle the
error.  Notice that the errors are raised up the stack in depositAmount: but
the handler is executed in deposit method.  This is very useful for some
very interesting but very hard to read hacks.  If someone is interested
please let me know.

Ok so now to answer your question.  Thought I'd never get here huh, if you
want to change the way an exception is raised you need to insert your own
handler before the default one catches it.

Try this: 

Execute the following in a workspace: 10/0 
Notice that the error class is ZeroDivide.  You can intercept the handler by
doing this.

[10/0] on: ZeroDivide do: [:ex | ex signal: 'Dividing by zero could destroy
the universe'].

Since you provided your own handler in the stack before the regular handler
could catch it you changed the message.

Please feel free to ask questions.

Happy coding!

Ron Teitelbaum
President / Principal Software Engineer
US Medical Record Specialists
Ron at USMedRec.com 

> From: Serdar Sahin
> Sent: Thursday, August 03, 2006 5:38 AM
>
> Hi,
>
> Is it possible to change some error messages ? For example, if i get 
> "Error: At least one digit expected here" error, i want to show my own 
> error message. Is that possible ?
>
> Thanks,



More information about the Beginners mailing list