[Seaside] custom error handling results in: "Error: context not in self"

Nick Ager nick.ager at gmail.com
Thu Sep 1 09:59:06 UTC 2011


>
> Nick and I sorted this out this evening. I assume he'll write up a
> summary... ;)
>

Indeed. If I understood the problem it's that capturing the exception in a
closure isn't sufficient, you need to break-off a continuation containing
the process to be debugged, then use that continuation to debug the problem.

The #handleException: code becomes:

handleException: ex
| renderContinuation shouldDebug |
renderContinuation := self createRenderContinuation.
 [
shouldDebug := self session presenter call: (WAWalkback current exception:
ex) ]
on: WARenderNotification
do: [ :exDontCare |
"redirect the main page to the error location"
self requestContext respond:
[ :response |
response
contentType: WAMimeType textHtml;
nextPutAll: (WARenderCanvas builder
fullDocument: true;
scriptGeneratorClass: JQScriptGenerator; "removes the onload from body"
render: [ :html |
html script: 'parent.parent.window.location.replace("', renderContinuation
registerForUrl greaseString, '")' ] )] ].

shouldDebug ifTrue: [
GRPlatform current openDebuggerOn: ex ]

Explanation:

#call: creates a continuation. However we trap the WARenderNotification to
allow us to render our own response. #call ,  #answer:(s) true if the user
clicks to debug the process. When #call: returns, it restores the state
prior to being called and the code continues executing at:

 shouldDebug ifTrue: [ GRPlatform current openDebuggerOn: ex ]

As the state has been restored we can open a debugger on the exception and
debug the original problem.

For comparison, our first implementation captured the continuation
explicitly,  though we decided the above solution was neater:

the lines:

    shouldDebug := self session presenter call: (WAWalkback current
exception: ex) ]
on: WARenderNotification
do: [ :exDontCare |

where replaced by:

shouldDebug := GRPlatform current seasideSuspendFlowDo: [ :cc |
session presenter show: (WAWalkback current exception: ex) onAnswer:
[:answer | cc value: answer ].

with the call to self requestContext respond: [...] inside the
#seasideSuspendFlowDo:

I extracted the code to create the render continuation into a method
#createRenderContinuation. If I understand correctly in Seaside3.1 there
will be methods on WARequestContext to allow you to create continuations,
which for example can be used to create a url for a callback from inside an
actionContinuation block.

I hope I haven't made the explanation more confusing than the code....

Nick


> On Tue, Aug 30, 2011 at 10:05 AM, Nick Ager <nick.ager at gmail.com> wrote:
>
>> Hi,
>>
>> I'm using a hidden iframe in my file upload component. If an error occurs
>> during uploading, the error page is rendered in the hidden iframe - which
>> means I end up debugging by inspecting the http responses in the browsers
>> development tools. Not ideal so I thought I'd trap the error and present the
>> page myself. In the exception trap I send a script to the page which
>> redirects the parent window to the error page -
>> 'parent.parent.window.location.replace(..error url..)' This works well apart
>> from when I click on the "debug" link, the debugger in the Pharo
>> reports: "Error: context not in self" and doesn't shows an unrelated (to the
>> original error) stack trace.
>>
>> I've patched together my error handling code, by examining the error
>> handling filter in Seaside. I've had to add an accessor on
>> WASession>>#continuations, which probably indicates there is an easier way
>> to achieve my goal:
>>
>> handleException: ex
>> | session requestContext key continuation renderContinuation |
>> requestContext := self requestContext.
>>  session := requestContext session.
>> key := requestContext request fields at: session actionField.
>>  continuation := session continuations at: key.
>> renderContinuation := continuation createRenderContinuation.
>>  session presenter show: (WAWalkback current exception: ex) onAnswer:
>> [:answer |
>> answer ifTrue: [
>>  self flag: #todo. "work out why I get the error: 'Error: context not in
>> self'"
>> GRPlatform current openDebuggerOn: ex ] ].
>>
>> "redirect the main page to the error location"
>> self requestContext respond:
>>  [ :response |
>> response
>> contentType: WAMimeType textHtml;
>>  nextPutAll: (WARenderCanvas builder
>> fullDocument: true;
>> scriptGeneratorClass: JQScriptGenerator; "removes the onload from body"
>>  render: [ :html |
>> html script: 'parent.parent.window.location.replace("', renderContinuation
>> registerForUrl  greaseString, '")' ] )]
>>
>> I've a horrible feeling I'm missing an obvious, simpler solution
>>
>> Thanks,
>>
>> Nick
>>
>> _______________________________________________
>> seaside mailing list
>> seaside at lists.squeakfoundation.org
>> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
>>
>>
>
> _______________________________________________
> seaside mailing list
> seaside at lists.squeakfoundation.org
> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/seaside/attachments/20110901/c65d7455/attachment.htm


More information about the seaside mailing list