Seaside and exception behaviour

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

Seaside and exception behaviour

Alan Knight-2
Hi All,
   Here's something interesting that came up with respect to Seaside in VisualWorks. The basic symptom is that if you have an error in a component, in Squeak you would get a debugger in the web browser. In VisualWorks you would get a debugger coming up in the image, and it would be on a somewhat different stack, the actual error being an unhandled render notification. The root of this seems to be a difference in exception behaviour between Squeak/Pharo and VisualWorks.

   The difference is a bit tricky to explain, so I'll also put in a code fragment that illustrates. Basically, if an exception is caught, and the handler block signals another exception, where does that exception begin looking for handlers. In VisualWorks, and in VisualAge, which are the only two I tested, it starts at the place it was raised. In Squeak and Pharo it appears that it starts at the, um, bottom again. This manifests in Seaside as
...
  Generic Error handler
    ...
      WARenderNotificationHandler
        ...
          error

So the error is raised, is caught by the generic error handler, and as a result it wants to display a debugger. Displaying a debugger wants to render a page, so it throws a WARenderNotification. But the only handler for that is further down in the stack, and so it's not caught. In Squeak and Pharo it appears that throwing that exception behaves more like resignalAs: behaves in VisualWorks (the resignalAs: method is a not yet implemented in VisualAge). Reading the ANSI specification, it's extraordinarily fuzzy about it, but I *think* it's describing the VisualWorks behaviour when it says

If a matching handler is found, the exception action of the handler is evaluated in the exception environment that was current when the handler was created and the state of the current exception environment is preserved as the signaling environment.


We think we can hack our way around that by specially coding Grease notifications to behave differently from other exceptions, but it's certainly not pretty, and it would be good if there was a cleaner way of dealing with it.

To more concretely illustrate what I'm talking about, consider defining an exception class ExceptionOne. Then define a class First with a method
startHere
    "First new startHere"
    [Second new doStuff] on: Error do: [:ex | Transcript cr; show: 'exception in startHere'. ExceptionOne signal].

And a class Second, with
doStuff
    [self doMoreStuff] on: ExceptionOne do: [:ex | Transcript cr; show: 'Exception in doStuff'].

and

doMoreStuff
    Transcript cr; show: 'Doing more stuff...'.
    3 / 0.

In VisualWorks and VisualAge that results in an uncaught ExceptionOne and a debugger. In Pharo 1.1 one-click it just prints 3 things to the Transcript, the same behaviour I'd get in VisualWorks if I change the startHere method to do "ex resiganlAs: ExceptionOne new"

-- 
Alan Knight [|], Engineering Manager, Cincom Smalltalk
[hidden email]
[hidden email]
http://www.cincom.com/smalltalk

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

Re: Seaside and exception behaviour

Paolo Bonzini-2
On 01/05/2011 03:25 PM, Alan Knight wrote:
> In Pharo 1.1 one-click it just prints 3 things to the Transcript, the
> same behaviour I'd get in VisualWorks if I change the startHere method
> to do "ex resiganlAs: ExceptionOne new"

FWIW GNU Smalltalk behaves the same as Squeak, independent of whether
ExceptionOne inherits from Notification or Error.  The implementation
was completely independent, FWIW.

The stack looks like

    #signal
    Handler for Error in #startHere
    #doMoreStuff
    #on:do: for #doStuff
    #doStuff
    #on:do: for #startHere (handler marked as busy)
    #startHere

When the search starts for the ExceptionOne handler, it will just search
for a non-busy handler.  *Any* handler that is not busy will do.  In
fact, if you have #on:do:on:do: you'll be able to execute the second
handler while the first is running.

Modulo getting the semantics of #on:do:on:do: right, it shouldn't be
hard to change GNU Smalltalk's behavior, and I'm curious if that will
break its testsuite...

> the same behaviour I'd get in VisualWorks if I change the startHere
> method to do "ex resiganlAs: ExceptionOne new"

That's not exactly the same.  #resignalAs: will reinstate _all_
handlers, while GNU Smalltalk will only pick those that are above the
currently running handler, and I think/hope Squeak does the same.

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

Re: Seaside and exception behaviour

mkobetic-2
In reply to this post by Alan Knight-2
Here's maybe a bit more concise example. If you run the thing below in a workspace,
it should return 'Squeak' in Squeak and 'VW' in VW

[ [ [ self error: 'trigger error'
                ] on: ZeroDivide do: [ :ex | 'Squeak' ]
        ] on: Error do: [ :ex | 3 / 0 ]
] on: ZeroDivide do: [ :ex | 'VW' ]

HTH,

Martin

"Alan Knight"<[hidden email]> wrote:

> To more concretely illustrate what I'm talking about, consider defining
> an exception class ExceptionOne. Then define a class First with a method
> startHere
>      "First new startHere"
>      [Second new doStuff] on: Error do: [:ex | Transcript cr; show:
> 'exception in startHere'. ExceptionOne signal].
>
> And a class Second, with
> doStuff
>      [self doMoreStuff] on: ExceptionOne do: [:ex | Transcript cr; show:
> 'Exception in doStuff'].
>
> and
>
> doMoreStuff
>      Transcript cr; show: 'Doing more stuff...'.
>      3 / 0.
>
> In VisualWorks and VisualAge that results in an uncaught ExceptionOne
> and a debugger. In Pharo 1.1 one-click it just prints 3 things to the
> Transcript, the same behaviour I'd get in VisualWorks if I change the
> startHere method to do "ex resiganlAs: ExceptionOne new"
>
> --
> Alan Knight [|], Engineering Manager, Cincom Smalltalk
> [hidden email]
> [hidden email]
> http://www.cincom.com/smalltalk
>
>
> _______________________________________________
> seaside-dev mailing list
> [hidden email]
> http://lists.squeakfoundation.org/mailman/listinfo/seaside-dev
>

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

Re: Seaside and exception behaviour

Paolo Bonzini-2
On 01/05/2011 04:08 PM, [hidden email] wrote:
> Here's maybe a bit more concise example. If you run the thing below in a workspace,
> it should return 'Squeak' in Squeak and 'VW' in VW
>
> [ [ [ self error: 'trigger error'
> ] on: ZeroDivide do: [ :ex | 'Squeak' ]
> ] on: Error do: [ :ex | 3 / 0 ]
> ] on: ZeroDivide do: [ :ex | 'VW' ]

It returns 'Squeak' on GNU Smalltalk.  This is consistent with my
analysis of Alan's snippet.  Unfortunately I don't have at hand my copy
of the standard.

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

Re: Seaside and exception behaviour

mkobetic-2
In reply to this post by Alan Knight-2
"Paolo Bonzini"<[hidden email]> wrote:

> On 01/05/2011 04:08 PM, [hidden email] wrote:
> > Here's maybe a bit more concise example. If you run the thing below in a workspace,
> > it should return 'Squeak' in Squeak and 'VW' in VW
> >
> > [ [ [ self error: 'trigger error'
> > ] on: ZeroDivide do: [ :ex | 'Squeak' ]
> > ] on: Error do: [ :ex | 3 / 0 ]
> > ] on: ZeroDivide do: [ :ex | 'VW' ]
>
> It returns 'Squeak' on GNU Smalltalk.  This is consistent with my
> analysis of Alan's snippet.  Unfortunately I don't have at hand my copy
> of the standard.

FWIW, Smalltalk/X returns 'VW'
_______________________________________________
seaside-dev mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/seaside-dev
Reply | Threaded
Open this post in threaded view
|

Re: Seaside and exception behaviour

Paolo Bonzini-2
On 01/05/2011 04:58 PM, [hidden email] wrote:

> > >  Here's maybe a bit more concise example. If you run the thing below in a workspace,
> > >  it should return 'Squeak' in Squeak and 'VW' in VW
> > >
> > >  [ [ [ self error: 'trigger error'
> > >   ] on: ZeroDivide do: [ :ex | 'Squeak' ]
> > >   ] on: Error do: [ :ex | 3 / 0 ]
> > >  ] on: ZeroDivide do: [ :ex | 'VW' ]
> >
> >  It returns 'Squeak' on GNU Smalltalk.  This is consistent with my
> >  analysis of Alan's snippet.  Unfortunately I don't have at hand my copy
> >  of the standard.
>
> FWIW, Smalltalk/X returns 'VW'

That's the correct behavior.  The standard says the search should
proceed from the last exception handler that was created up to the oldest.

(That said, Squeak/gst's behavior is quite easy to justify, as stack
unwinding hasn't happened yet.  I'll wait for this thread to settle
before changing it in gst).

Does VW have #on:do:on:do:?  If so, what happens for

        [ [ self error: 'trigger error'
    ] on: ZeroDivide do: [ :ex | 'Squeak' ]
    ] on: Error do: [ :ex | 3 / 0 ]
          on: ZeroDivide do: [ :ex | 'VW' ]

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

Re: Seaside and exception behaviour

mkobetic-2
In reply to this post by Alan Knight-2
"Paolo Bonzini"<[hidden email]> wrote:
> Does VW have #on:do:on:do:?  If so, what happens for
>
> [ [ self error: 'trigger error'
>     ] on: ZeroDivide do: [ :ex | 'Squeak' ]
>     ] on: Error do: [ :ex | 3 / 0 ]
>  on: ZeroDivide do: [ :ex | 'VW' ]

It doesn't. Personally, without knowing much about the intent of on:do:on:do:, I'd intuitively expect to get a ZeroDivide exception out of this, i.e. if the Error handler raises ZeroDivide, both ZeroDivide handlers should be out of scope at that point. Unless on:do:on:do: is meant to be just a shortcut for [ on:do: ] on:do:. Or to put it differently I'd expect on: X do: [X] on: Y do: [Y] to be equivalent to on: X, Y do: [ :ex | (X handles: ex) ifTrue: [X] ifFalse: [Y]], if that makes sense.
_______________________________________________
seaside-dev mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/seaside-dev
Reply | Threaded
Open this post in threaded view
|

Re: Seaside and exception behaviour

John O'Keefe
In reply to this post by Paolo Bonzini-2

John O'Keefe [|], Principal Smalltalk Architect, Instantiations Inc.
Skype: john_okeefe2     Mobile:  +1 919 417-3181 (Business hours USA Eastern Time zone (GMT -5))
[hidden email]
http://www.instantiations.com
VA Smalltalk...Onward and Upward!


On Wed, Jan 5, 2011 at 11:15 AM, Paolo Bonzini <[hidden email]> wrote:
On 01/05/2011 04:58 PM, [hidden email] wrote:
> >  Here's maybe a bit more concise example. If you run the thing below in a workspace,
> >  it should return 'Squeak' in Squeak and 'VW' in VW
> >
> >  [  [       [       self error: 'trigger error'
> >             ] on: ZeroDivide do: [ :ex | 'Squeak' ]
> >     ] on: Error do: [ :ex | 3 / 0 ]
> >  ] on: ZeroDivide do: [ :ex | 'VW' ]
>
>  It returns 'Squeak' on GNU Smalltalk.  This is consistent with my
>  analysis of Alan's snippet.  Unfortunately I don't have at hand my copy
>  of the standard.

FWIW, Smalltalk/X returns 'VW'

That's the correct behavior.  The standard says the search should proceed from the last exception handler that was created up to the oldest.

(That said, Squeak/gst's behavior is quite easy to justify, as stack unwinding hasn't happened yet.  I'll wait for this thread to settle before changing it in gst).

Does VW have #on:do:on:do:?  If so, what happens for

       [       [       self error: 'trigger error'

               ] on: ZeroDivide do: [ :ex | 'Squeak' ]
       ] on: Error do: [ :ex | 3 / 0 ]
         on: ZeroDivide do: [ :ex | 'VW' ]

Paolo
 
VA Smalltalk returns 'VW' (as expected) for the first snippet.  VA Smalltalk does not implement on:do:on:do:.

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

Re: Seaside and exception behaviour

Philippe Marschall
In reply to this post by Alan Knight-2
2011/1/5 Alan Knight <[hidden email]>:

> Hi All,
>    Here's something interesting that came up with respect to Seaside in
> VisualWorks. The basic symptom is that if you have an error in a component,
> in Squeak you would get a debugger in the web browser. In VisualWorks you
> would get a debugger coming up in the image, and it would be on a somewhat
> different stack, the actual error being an unhandled render notification.
> The root of this seems to be a difference in exception behaviour between
> Squeak/Pharo and VisualWorks.
>
>    The difference is a bit tricky to explain, so I'll also put in a code
> fragment that illustrates. Basically, if an exception is caught, and the
> handler block signals another exception, where does that exception begin
> looking for handlers. In VisualWorks, and in VisualAge, which are the only
> two I tested, it starts at the place it was raised. In Squeak and Pharo it
> appears that it starts at the, um, bottom again. This manifests in Seaside
> as
> ...
>   Generic Error handler
>     ...
>       WARenderNotificationHandler
>         ...
>           error
>
> So the error is raised, is caught by the generic error handler, and as a
> result it wants to display a debugger. Displaying a debugger wants to render
> a page, so it throws a WARenderNotification. But the only handler for that
> is further down in the stack, and so it's not caught. In Squeak and Pharo it
> appears that throwing that exception behaves more like resignalAs: behaves
> in VisualWorks (the resignalAs: method is a not yet implemented in
> VisualAge). Reading the ANSI specification, it's extraordinarily fuzzy about
> it, but I *think* it's describing the VisualWorks behaviour when it says
>
> If a matching handler is found, the exception action of the handler is
> evaluated in the exception environment that was current when the handler was
> created and the state of the current exception environment is preserved as
> the signaling environment.
>
> We think we can hack our way around that by specially coding Grease
> notifications to behave differently from other exceptions, but it's
> certainly not pretty, and it would be good if there was a cleaner way of
> dealing with it.
>
> To more concretely illustrate what I'm talking about, consider defining an
> exception class ExceptionOne. Then define a class First with a method
> startHere
>     "First new startHere"
>     [Second new doStuff] on: Error do: [:ex | Transcript cr; show:
> 'exception in startHere'. ExceptionOne signal].
>
> And a class Second, with
> doStuff
>     [self doMoreStuff] on: ExceptionOne do: [:ex | Transcript cr; show:
> 'Exception in doStuff'].
>
> and
>
> doMoreStuff
>     Transcript cr; show: 'Doing more stuff...'.
>     3 / 0.
>
> In VisualWorks and VisualAge that results in an uncaught ExceptionOne and a
> debugger. In Pharo 1.1 one-click it just prints 3 things to the Transcript,
> the same behaviour I'd get in VisualWorks if I change the startHere method
> to do "ex resiganlAs: ExceptionOne new"

Wow, you always learn something new. Please file an issue [1] and
don't hesitate to suggest a fix ;-)

 [1] http://code.google.com/p/seaside/issues/list

Cheers
Philippe
_______________________________________________
seaside-dev mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/seaside-dev
Reply | Threaded
Open this post in threaded view
|

Re: Seaside and exception behaviour

Julian Fitzell-2
In reply to this post by Paolo Bonzini-2
On Wed, Jan 5, 2011 at 8:15 AM, Paolo Bonzini <[hidden email]> wrote:

> On 01/05/2011 04:58 PM, [hidden email] wrote:
>>
>> > >  Here's maybe a bit more concise example. If you run the thing below
>> > > in a workspace,
>> > >  it returns 'Squeak' in Squeak and 'VW' in VW
>> > >
>> > >  [  [       [       self error: 'trigger error'
>> > >             ] on: ZeroDivide do: [ :ex | 'Squeak' ]
>> > >     ] on: Error do: [ :ex | 3 / 0 ]
>> > >  ] on: ZeroDivide do: [ :ex | 'VW' ]
>> >
>> >  It returns 'Squeak' on GNU Smalltalk.  This is consistent with my
>> >  analysis of Alan's snippet.  Unfortunately I don't have at hand my copy
>> >  of the standard.
>>
>> FWIW, Smalltalk/X returns 'VW'
>
> That's the correct behavior.  The standard says the search should proceed
> from the last exception handler that was created up to the oldest.

Agreed.  The ANSI standard seems quite clear about that:

5.4.3.3: "If signaling of an exception results in evaluation of action
the evaluation will occur in the context of the handler environment."

5.5.2.1: "If a matching handler is found, the exception action of the
handler is evaluated in the exception environment that was current
when the handler was created and the state of the current exception
environment is preserved as the signaling environment."

> (That said, Squeak/gst's behavior is quite easy to justify, as stack
> unwinding hasn't happened yet.  I'll wait for this thread to settle before
> changing it in gst).

But stack unwinding shouldn't need to happen until one of the #on:do:
calls is actually ready to return. Until then, its all just searching.

I think Squeak/Pharo's problem is that it doesn't maintain a first
class "exception environment" as described by the glossary in the ANSI
standard: "An abstract entity that is a LIFO list of exception
handlers. An exception environment may be logically searched starting
from the most recently "pushed" exception handler."

Squeak/Pharo simply (ab)uses the context chain, walking it looking for
the next handler (see the implementation of #signal, which always
starts searching from thisContext). This works fine most of the time
but not when you need to temporarily restore a previous exception
environment. #handleSignal: does go to the effort of setting a
handlerContext on the signaled exception before calling the action
block. This is necessary to implement #pass, #isNested, and so on but
would also need to be put somewhere that #signal could get at it to
use as a starting point for the search.

This seems like a squeak/pharo bug to me. I don't much feel like
fixing it in Grease given that Grease is supposed to assume correct
ANSI implementation as a pre-requisite. Perhaps we can broker a deal
where Squeak/Pharo will fix this and VW (finally) fixes its signaling
behaviour so we can drop GRError, etc. entirely.

In the meantime, though, how would we fix the Seaside code assuming we
had ANSI-correct exception handling implementations?

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

Re: Seaside and exception behaviour

Paolo Bonzini-2
In reply to this post by mkobetic-2
On Wed, Jan 5, 2011 at 17:23,  <[hidden email]> wrote:
> "Paolo Bonzini"<[hidden email]> wrote:
>> Does VW have #on:do:on:do:?  If so, what happens for
>>
>>       [       [       self error: 'trigger error'
>>               ] on: ZeroDivide do: [ :ex | 'Squeak' ]
>>       ] on: Error do: [ :ex | 3 / 0 ]
>>         on: ZeroDivide do: [ :ex | 'VW' ]
>
> It doesn't. Personally, without knowing much about the intent of on:do:on:do

It's the same as two nested on:do: except that: 1) the handlers are
automatically reordered so that the most specific goes first; 2) after
this change, search would start outside _both_ handlers.

> Or to put it differently I'd expect on: X do: [X] on: Y do: [Y] to be
> equivalent to on: X, Y do: [ :ex | (X handles: ex) ifTrue: [X] ifFalse: [Y]],
> if that makes sense.

Yes, that would take care of (2).

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

Re: [squeak-dev] Re: [Seaside-dev] Seaside and exception behaviour

Julian Fitzell-2
In reply to this post by Julian Fitzell-2
Hi Andreas,

A neat approach, but I don't think it quite works (yet, anyway).
Although it has the correct behaviour when the exception action is
invoked, it doesn't behave correctly for #defaultAction. According to
5.5.2.1 in the spec, "The #defaultAction method is executed in the
context of the signaling environment."

So, taking an example of an existing #defaultAction method that
signals an exception:

[ Error signal ] on: UnhandledError do: [ :ex | 'ANSI says so' ]

returns 'ANSI says so' without your change but brings up a debugger with it.

Julian

On Sat, Jan 8, 2011 at 7:34 PM, Andreas Raab <[hidden email]> wrote:

> Thanks for the test case. I've posted a possible fix for Squeak to the inbox
> (Kernel-ar.540) but I'd like people to review the change first since it's a
> fairly critical part of the system. I'd appreciate if someone could look at
> the fix and comment on whether that's the sensible thing to do.
>
> Cheers,
>  - Andreas
>
> On 1/8/2011 6:02 PM, Julian Fitzell wrote:
>>
>> On Wed, Jan 5, 2011 at 8:15 AM, Paolo Bonzini<[hidden email]>  wrote:
>>>
>>> On 01/05/2011 04:58 PM, [hidden email] wrote:
>>>>
>>>>>>  Here's maybe a bit more concise example. If you run the thing below
>>>>>> in a workspace,
>>>>>>  it returns 'Squeak' in Squeak and 'VW' in VW
>>>>>>
>>>>>>  [  [       [       self error: 'trigger error'
>>>>>>             ] on: ZeroDivide do: [ :ex | 'Squeak' ]
>>>>>>     ] on: Error do: [ :ex | 3 / 0 ]
>>>>>>  ] on: ZeroDivide do: [ :ex | 'VW' ]
>>>>>
>>>>>  It returns 'Squeak' on GNU Smalltalk.  This is consistent with my
>>>>>  analysis of Alan's snippet.  Unfortunately I don't have at hand my
>>>>> copy
>>>>>  of the standard.
>>>>
>>>> FWIW, Smalltalk/X returns 'VW'
>>>
>>> That's the correct behavior.  The standard says the search should proceed
>>> from the last exception handler that was created up to the oldest.
>>
>> Agreed.  The ANSI standard seems quite clear about that:
>>
>> 5.4.3.3: "If signaling of an exception results in evaluation of action
>> the evaluation will occur in the context of the handler environment."
>>
>> 5.5.2.1: "If a matching handler is found, the exception action of the
>> handler is evaluated in the exception environment that was current
>> when the handler was created and the state of the current exception
>> environment is preserved as the signaling environment."
>>
>>> (That said, Squeak/gst's behavior is quite easy to justify, as stack
>>> unwinding hasn't happened yet.  I'll wait for this thread to settle
>>> before
>>> changing it in gst).
>>
>> But stack unwinding shouldn't need to happen until one of the #on:do:
>> calls is actually ready to return. Until then, its all just searching.
>>
>> I think Squeak/Pharo's problem is that it doesn't maintain a first
>> class "exception environment" as described by the glossary in the ANSI
>> standard: "An abstract entity that is a LIFO list of exception
>> handlers. An exception environment may be logically searched starting
>> from the most recently "pushed" exception handler."
>>
>> Squeak/Pharo simply (ab)uses the context chain, walking it looking for
>> the next handler (see the implementation of #signal, which always
>> starts searching from thisContext). This works fine most of the time
>> but not when you need to temporarily restore a previous exception
>> environment. #handleSignal: does go to the effort of setting a
>> handlerContext on the signaled exception before calling the action
>> block. This is necessary to implement #pass, #isNested, and so on but
>> would also need to be put somewhere that #signal could get at it to
>> use as a starting point for the search.
>>
>> This seems like a squeak/pharo bug to me. I don't much feel like
>> fixing it in Grease given that Grease is supposed to assume correct
>> ANSI implementation as a pre-requisite. Perhaps we can broker a deal
>> where Squeak/Pharo will fix this and VW (finally) fixes its signaling
>> behaviour so we can drop GRError, etc. entirely.
>>
>> In the meantime, though, how would we fix the Seaside code assuming we
>> had ANSI-correct exception handling implementations?
>>
>> Julian
>>
>>
>
>
>
_______________________________________________
seaside-dev mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/seaside-dev
Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: [Seaside-dev] Seaside and exception behaviour

Andreas.Raab
Thanks. That's exactly why I wanted someone to review the approach. I'll
go back to the drawing board and see if I can come up with something
better :-)

Cheers,
   - Andreas

On 1/9/2011 9:47 PM, Julian Fitzell wrote:

> Hi Andreas,
>
> A neat approach, but I don't think it quite works (yet, anyway).
> Although it has the correct behaviour when the exception action is
> invoked, it doesn't behave correctly for #defaultAction. According to
> 5.5.2.1 in the spec, "The #defaultAction method is executed in the
> context of the signaling environment."
>
> So, taking an example of an existing #defaultAction method that
> signals an exception:
>
> [ Error signal ] on: UnhandledError do: [ :ex | 'ANSI says so' ]
>
> returns 'ANSI says so' without your change but brings up a debugger with it.
>
> Julian
>
> On Sat, Jan 8, 2011 at 7:34 PM, Andreas Raab<[hidden email]>  wrote:
>> Thanks for the test case. I've posted a possible fix for Squeak to the inbox
>> (Kernel-ar.540) but I'd like people to review the change first since it's a
>> fairly critical part of the system. I'd appreciate if someone could look at
>> the fix and comment on whether that's the sensible thing to do.
>>
>> Cheers,
>>   - Andreas
>>
>> On 1/8/2011 6:02 PM, Julian Fitzell wrote:
>>>
>>> On Wed, Jan 5, 2011 at 8:15 AM, Paolo Bonzini<[hidden email]>    wrote:
>>>>
>>>> On 01/05/2011 04:58 PM, [hidden email] wrote:
>>>>>
>>>>>>>   Here's maybe a bit more concise example. If you run the thing below
>>>>>>> in a workspace,
>>>>>>>   it returns 'Squeak' in Squeak and 'VW' in VW
>>>>>>>
>>>>>>>   [  [       [       self error: 'trigger error'
>>>>>>>              ] on: ZeroDivide do: [ :ex | 'Squeak' ]
>>>>>>>      ] on: Error do: [ :ex | 3 / 0 ]
>>>>>>>   ] on: ZeroDivide do: [ :ex | 'VW' ]
>>>>>>
>>>>>>   It returns 'Squeak' on GNU Smalltalk.  This is consistent with my
>>>>>>   analysis of Alan's snippet.  Unfortunately I don't have at hand my
>>>>>> copy
>>>>>>   of the standard.
>>>>>
>>>>> FWIW, Smalltalk/X returns 'VW'
>>>>
>>>> That's the correct behavior.  The standard says the search should proceed
>>>> from the last exception handler that was created up to the oldest.
>>>
>>> Agreed.  The ANSI standard seems quite clear about that:
>>>
>>> 5.4.3.3: "If signaling of an exception results in evaluation of action
>>> the evaluation will occur in the context of the handler environment."
>>>
>>> 5.5.2.1: "If a matching handler is found, the exception action of the
>>> handler is evaluated in the exception environment that was current
>>> when the handler was created and the state of the current exception
>>> environment is preserved as the signaling environment."
>>>
>>>> (That said, Squeak/gst's behavior is quite easy to justify, as stack
>>>> unwinding hasn't happened yet.  I'll wait for this thread to settle
>>>> before
>>>> changing it in gst).
>>>
>>> But stack unwinding shouldn't need to happen until one of the #on:do:
>>> calls is actually ready to return. Until then, its all just searching.
>>>
>>> I think Squeak/Pharo's problem is that it doesn't maintain a first
>>> class "exception environment" as described by the glossary in the ANSI
>>> standard: "An abstract entity that is a LIFO list of exception
>>> handlers. An exception environment may be logically searched starting
>>> from the most recently "pushed" exception handler."
>>>
>>> Squeak/Pharo simply (ab)uses the context chain, walking it looking for
>>> the next handler (see the implementation of #signal, which always
>>> starts searching from thisContext). This works fine most of the time
>>> but not when you need to temporarily restore a previous exception
>>> environment. #handleSignal: does go to the effort of setting a
>>> handlerContext on the signaled exception before calling the action
>>> block. This is necessary to implement #pass, #isNested, and so on but
>>> would also need to be put somewhere that #signal could get at it to
>>> use as a starting point for the search.
>>>
>>> This seems like a squeak/pharo bug to me. I don't much feel like
>>> fixing it in Grease given that Grease is supposed to assume correct
>>> ANSI implementation as a pre-requisite. Perhaps we can broker a deal
>>> where Squeak/Pharo will fix this and VW (finally) fixes its signaling
>>> behaviour so we can drop GRError, etc. entirely.
>>>
>>> In the meantime, though, how would we fix the Seaside code assuming we
>>> had ANSI-correct exception handling implementations?
>>>
>>> Julian
>>>
>>>
>>
>>
>>
> _______________________________________________
> seaside-dev mailing list
> [hidden email]
> http://lists.squeakfoundation.org/mailman/listinfo/seaside-dev
>
_______________________________________________
seaside-dev mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/seaside-dev
Reply | Threaded
Open this post in threaded view
|

Re: Seaside and exception behaviour

Dale Henrichs
In reply to this post by mkobetic-2
GemStone2.x gets 'Squeak' and GemStone3.x gets 'VW':)

In GemStone2.x ANSI exception behavior was added onto the existing
(non-ANSI) exception handling framework.

In GemStone3.x we converted our exception handling framework to be
ANSI-based...

Dale

On 01/05/2011 07:08 AM, [hidden email] wrote:

> Here's maybe a bit more concise example. If you run the thing below in a workspace,
> it should return 'Squeak' in Squeak and 'VW' in VW
>
> [ [ [ self error: 'trigger error'
> ] on: ZeroDivide do: [ :ex | 'Squeak' ]
> ] on: Error do: [ :ex | 3 / 0 ]
> ] on: ZeroDivide do: [ :ex | 'VW' ]
>
> HTH,
>
> Martin
>
> "Alan Knight"<[hidden email]>  wrote:
>> To more concretely illustrate what I'm talking about, consider defining
>> an exception class ExceptionOne. Then define a class First with a method
>> startHere
>>       "First new startHere"
>>       [Second new doStuff] on: Error do: [:ex | Transcript cr; show:
>> 'exception in startHere'. ExceptionOne signal].
>>
>> And a class Second, with
>> doStuff
>>       [self doMoreStuff] on: ExceptionOne do: [:ex | Transcript cr; show:
>> 'Exception in doStuff'].
>>
>> and
>>
>> doMoreStuff
>>       Transcript cr; show: 'Doing more stuff...'.
>>       3 / 0.
>>
>> In VisualWorks and VisualAge that results in an uncaught ExceptionOne
>> and a debugger. In Pharo 1.1 one-click it just prints 3 things to the
>> Transcript, the same behaviour I'd get in VisualWorks if I change the
>> startHere method to do "ex resiganlAs: ExceptionOne new"
>>
>> --
>> Alan Knight [|], Engineering Manager, Cincom Smalltalk
>> [hidden email]
>> [hidden email]
>> http://www.cincom.com/smalltalk
>>
>>
>> _______________________________________________
>> seaside-dev mailing list
>> [hidden email]
>> http://lists.squeakfoundation.org/mailman/listinfo/seaside-dev
>>
>
> _______________________________________________
> seaside-dev mailing list
> [hidden email]
> http://lists.squeakfoundation.org/mailman/listinfo/seaside-dev

_______________________________________________
seaside-dev mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/seaside-dev