Changing error message

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

Changing error message

Serdar Sahin

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,


_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Changing error message

stéphane ducasse-2
Hi

you should tell us more if you want real help :)

Stef

On 3 août 06, at 11:38, Serdar Sahin wrote:

> 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,
>
> _______________________________________________
> Beginners mailing list
> [hidden email]
> http://lists.squeakfoundation.org/mailman/listinfo/beginners

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

RE: Changing error message

Serdar Sahin

Hi,

Thank you for your response.

Yes, you are right, i forgot to give some necessary information. But i will
solve, i guess, i am trying to write that code. I do not have any question
for now.

Sorry and Thanks, :)




-----Original Message-----
From: [hidden email]
[mailto:[hidden email]] On Behalf Of stéphane
ducasse
Sent: Thursday, August 03, 2006 7:55 PM
To: A friendly place to get answers to even the most basic questions
aboutSqueak.
Subject: Re: [Newbies] Changing error message

Hi

you should tell us more if you want real help :)

Stef

On 3 août 06, at 11:38, Serdar Sahin wrote:

> 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,
>
> _______________________________________________
> Beginners mailing list
> [hidden email]
> http://lists.squeakfoundation.org/mailman/listinfo/beginners

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

RE: Changing error message

Ron Teitelbaum
In reply to this post by Serdar Sahin
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
[hidden email]

> 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,

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

RE: Changing error message

Serdar Sahin
Hi Ron,

Thank you very much. It makes perfect sense. Now i am trying to practise it.
Thank you again..

Serdar Sahin

-----Original Message-----
From: [hidden email]
[mailto:[hidden email]] On Behalf Of Ron
Teitelbaum
Sent: Friday, August 04, 2006 2:01 AM
To: 'A friendly place to get answers to even the most basic
questionsaboutSqueak.'
Subject: RE: [Newbies] Changing error message

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
[hidden email]

> 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,

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Changing error message

cedreek
In reply to this post by Ron Teitelbaum
really interesting...

If I remember well I've seen Stephan saying that it's not always good practises tu use exception handling ...

what are the limits ? when to use or when not to use ...

It seems appropriate to me when there is a user entry to control it and avoid human input error (WAValidationDecoration in seaside uses WAValidationNotification for the Store example for instance) therwise, I don't really see...






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.


I am :)


Thanks ;)

Cédrick



_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Changing error message

Roel Wuyts
Exception handling should be used to capture exceptional situation  
that are beyond the control of your application, such as permission  
errors on files etc.

It should not be used to implement a particular control flow. For  
example, you can use an exception to return out of a particular  
context and return control to some other context. We saw this in an  
application that needed to traverse a tree of object, and whenever it  
needed to backtrack it raised an error which was caught at the  
decision point. So instead of properly implementing the object  
traversal, exceptions were used to control the traversal.



On 21 Aug 2006, at 17:09, cdrick wrote:

> really interesting...
>
> If I remember well I've seen Stephan saying that it's not always  
> good practises tu use exception handling ...
>
> what are the limits ? when to use or when not to use ...
>
> It seems appropriate to me when there is a user entry to control it  
> and avoid human input error (WAValidationDecoration in seaside uses  
> WAValidationNotification for the Store example for instance)  
> therwise, I don't really see...
>
>
>
>
>
>
> 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.
>
>
> I am :)
>
>
> Thanks ;)
>
> Cédrick
>
>
> _______________________________________________
> Beginners mailing list
> [hidden email]
> http://lists.squeakfoundation.org/mailman/listinfo/beginners

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Changing error message

Damien Cassou-3
In reply to this post by cedreek
cdrick wrote:

> really interesting...
>
> If I remember well I've seen Stephan saying that it's not always good
> practises tu use exception handling ...
>
> what are the limits ? when to use or when not to use ...
>
> It seems appropriate to me when there is a user entry to control it and
> avoid human input error (WAValidationDecoration in seaside uses
> WAValidationNotification for the Store example for instance) therwise, I
> don't really see...


I often use error handling to detect errors in parameters in the model.
Most of the time, I assume parameters are valid but sometimes I must be
sure. Then, if the parameter is not valid I throw (or raise) an
exception (not using #error: but a self-made subclass of Error). The
error can be catched when there is something to do or you can let it
notify the user about a problem (use a string describing clearly the
problem).
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

RE: Changing error message

Ron Teitelbaum
In reply to this post by cedreek
Hi Cédrick,

Ok first remember that this is a HACK and is not intended for regular use.
So before I give you the hack I want to tell you a little about proper
programming.

1) Methods should be short.  Only a few lines long.
2) You usually don't need a lot of parameters in methods.  If you have too
many parameters then you are probably missing an object.
3) Methods should care about self.  If you don’t see self in your instance
method then you are probably programming on the wrong object.  Pay attention
to where you put your code.  If self is really not needed then you should
probably be writing your code on the class side.
4) Avoid hard coded values, use references when possible.

Ok so now here is the hack.  Say you have been writing code for months and
you finally have everything you want just so.  Someone then says, hey can
you add this or that, and you realize that there is data missing to get it
done.  I started on Object A with the right info but by the time I got to
Object G hundreds of methods away it has no idea about Object A or what data
was used to create it.  What am I going to do?  The answer is to use
exception handling as a way to pass a parameter. (I told you it was a hack).

How about an example:

CashRegister >> saleItem: anItem price: aPrice taxRate: aTaxRate
        "adjust inventory, record taxes and update receipt"
        self inventory removeItem: anItem.
        self recordTax: aPrice taxRate: aTaxRate.
        self receipt addItem: anItem.

CashRegister >> recordTax: aPrice taxRate: aTaxRate
        "record taxes to be paid later"
        self taxPeriod recordTax: aPrice taxRate: aTaxRate

CashRegister >> taxPeriod
        "get the current Tax period"
        ^Tax getPeriod: Date today.

This was great until someone said to you, we need to go back and re run all
of our receipts to generate a tax report because we were just audited and we
didn't charge enough tax because our system had the wrong tax rate.  You go
and look at the code and say to yourself, "Self the code doesn't even
mention date anywhere accept using the current tax period, Do I need to
rewrite all the code to get this to work?"  

I'm sure you could come up with better examples of this; I'm just making
this up.  Also be aware there are better ways to solve this problem, but
here is one.  Assume that this is difficult for some reason like the dates
the items were sold can only come from the inventory.  Since you will be
processing your new tax report from each item the dates are all jumbled up.

If you wrap your code in an exception handler

        Inventory allItems do: [:anItem |
                soldOn := anItem saleDate.
                aPrice := anItem salePrice.
                aTaxRate := anItem correctTaxRateForDate: soldOn.
                [myRegister saleItem: anItem price: aPrice taxRate: aTaxRate
                ] on: GetSaleDateError
          do: [:ex | ex resume: soldOn].
       
Now in your CashRegister >> taxPeriod code you write:

CashRegister >> taxPeriod
        "get the current Tax period"
        ^Tax getPeriod: GetSaleDateError raise.

In order to not break your regular code you will need to wrap the normal
call to saleItem:price:taxRate: with:

on: GetSaleDateError do: [:ex | ex resume: Date today].

Like I said it is a hack, and very hard to read and bad form, but if your
parameters are very far away it can be a life saver.  And again all of this
could have been prevented by using a better design and anticipating problems
with things like hard coded dates.

Notice that the do: block is in the context of the method when it was
executed which means you have access in that block to anything within that
method.  

Hope that helps, (Don't tell anyone I mentioned this !^)

Ron Teitelbaum




________________________________________
From: cdrick [mailto:[hidden email]]
Sent: Monday, August 21, 2006 11:09 AM
To: [hidden email]; A friendly place to get answers to even the most basic
questions about Squeak.
Subject: Re: [Newbies] Changing error message

really interesting...

If I remember well I've seen Stephan saying that it's not always good
practises tu use exception handling ...

what are the limits ? when to use or when not to use ...

It seems appropriate to me when there is a user entry to control it and
avoid human input error (WAValidationDecoration in seaside uses
WAValidationNotification for the Store example for instance) therwise, I
don't really see...





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.


I am :)


Thanks ;)

Cédrick



_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Exception hacks (was Re: Changing error message)

Bert Freudenberg-3
Ron Teitelbaum schrieb:

> In order to not break your regular code you will need to wrap the normal
> call to saleItem:price:taxRate: with:
>
> on: GetSaleDateError do: [:ex | ex resume: Date today].

Actually there is no need to wrap any regular code, if you do it
properly ;-)

You should not call this GetSaleDateError but, say, SaleDateHack and
make it a Notification subclass. Unlike Error subclasses, Notification
subclasses work fine even without an on:do: exception handler. That's
because their #defaultAction simply answers nil instead of opening the
debugger.

If there is no handler, "SaleDateHack signal" will simply answer nil, so
you can replace your original "Date today" code with

        date := SaleDateHack signal ifNil: [Date today].

(this is even better design-wise than implementing your notification's
#defaultAction as "self resume: Date today" because you see the default
value right where it is used, rather than hidden in the notifiction class)

>  (Don't tell anyone I mentioned this !^)

Don't tell anyone I replied to this on the *newbies* list - I'd consider
this well advanced. It's fun stuff anyway ;-)

- Bert -
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Exception hacks (was Re: Changing error message)

cedreek
> You should not call this GetSaleDateError but, say, SaleDateHack
hehe ;) nice pattern...  intention revealing selector is that it ? lol

> make it a Notification subclass. Unlike Error subclasses, Notification
> subclasses work fine even without an on:do: exception handler. That's
> because their #defaultAction simply answers nil instead of opening the
> debugger.
>
> If there is no handler, "SaleDateHack signal" will simply answer nil, so
> you can replace your original "Date today" code with
>
>         date := SaleDateHack signal ifNil: [Date today].
>
> (this is even better design-wise than implementing your notification's
> #defaultAction as "self resume: Date today" because you see the default
> value right where it is used, rather than hidden in the notifiction class)
cool :)

>
> >  (Don't tell anyone I mentioned this !^)
>
> Don't tell anyone I replied to this on the *newbies* list - I'd consider
> this well advanced. It's fun stuff anyway ;-)

maybe an advanced list ?  just kidding ;)
but this make me understand better

Thanks ;)

Cédrick

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

RE: Exception hacks (was Re: Changing error message)

Ron Teitelbaum
In reply to this post by Bert Freudenberg-3
Thanks Bert,

That is a very nice addition.  

Learn something every day!

Ron Teitelbaum

> -----Original Message-----
> From: [hidden email] [mailto:beginners-
> [hidden email]] On Behalf Of Bert Freudenberg
> Sent: Tuesday, August 22, 2006 5:33 AM
> To: A friendly place to get answers to even the most basic questions
> aboutSqueak.
> Subject: Exception hacks (was Re: [Newbies] Changing error message)
>
> Ron Teitelbaum schrieb:
>
> > In order to not break your regular code you will need to wrap the normal
> > call to saleItem:price:taxRate: with:
> >
> > on: GetSaleDateError do: [:ex | ex resume: Date today].
>
> Actually there is no need to wrap any regular code, if you do it
> properly ;-)
>
> You should not call this GetSaleDateError but, say, SaleDateHack and
> make it a Notification subclass. Unlike Error subclasses, Notification
> subclasses work fine even without an on:do: exception handler. That's
> because their #defaultAction simply answers nil instead of opening the
> debugger.
>
> If there is no handler, "SaleDateHack signal" will simply answer nil, so
> you can replace your original "Date today" code with
>
> date := SaleDateHack signal ifNil: [Date today].
>
> (this is even better design-wise than implementing your notification's
> #defaultAction as "self resume: Date today" because you see the default
> value right where it is used, rather than hidden in the notifiction class)
>
> >  (Don't tell anyone I mentioned this !^)
>
> Don't tell anyone I replied to this on the *newbies* list - I'd consider
> this well advanced. It's fun stuff anyway ;-)
>
> - Bert -
> _______________________________________________
> Beginners mailing list
> [hidden email]
> http://lists.squeakfoundation.org/mailman/listinfo/beginners


_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners