[Seaside] custom error handling results in: "Error: context not
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:
| renderContinuation shouldDebug |
renderContinuation := self createRenderContinuation.
shouldDebug := self session presenter call: (WAWalkback current exception:
do: [ :exDontCare |
"redirect the main page to the error location"
self requestContext respond:
[ :response |
contentType: WAMimeType textHtml;
nextPutAll: (WARenderCanvas builder
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 ]
#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:
shouldDebug := self session presenter call: (WAWalkback current
exception: ex) ]
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
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
I hope I haven't made the explanation more confusing than the code....
> On Tue, Aug 30, 2011 at 10:05 AM, Nick Ager <nick.ager at gmail.com> wrote:
>> 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
>> GRPlatform current openDebuggerOn: ex ] ].
>> "redirect the main page to the error location"
>> self requestContext respond:
>> [ :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
>> seaside mailing list
>> seaside at lists.squeakfoundation.org
> seaside mailing list
> seaside at lists.squeakfoundation.org
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the seaside