<div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">Nick and I sorted this out this evening. I assume he'll write up a summary... ;)<br></blockquote>
<div> </div><div>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.</div>
<div><br></div><div>The #handleException: code becomes:</div><div><br></div><div><div>handleException: ex</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>| renderContinuation shouldDebug |</div><div>
<span class="Apple-tab-span" style="white-space:pre">        </span>renderContinuation := self createRenderContinuation.</div><div><span class="Apple-tab-span" style="white-space:pre">        </span></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>[</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>shouldDebug := self session presenter call: (WAWalkback current exception: ex) ]</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>on: WARenderNotification </div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>do: [ :exDontCare |</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>"redirect the main page to the error location"</div><div>
<span class="Apple-tab-span" style="white-space:pre">                </span>self requestContext respond: </div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>[ :response | </div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>response</div>
<div><span class="Apple-tab-span" style="white-space:pre">                                </span>contentType: WAMimeType textHtml;</div><div><span class="Apple-tab-span" style="white-space:pre">                                </span>nextPutAll: (WARenderCanvas builder</div><div>
<span class="Apple-tab-span" style="white-space:pre">                                        </span>fullDocument: true;</div><div><span class="Apple-tab-span" style="white-space:pre">                                        </span>scriptGeneratorClass: JQScriptGenerator; "removes the onload from body"</div>
<div><span class="Apple-tab-span" style="white-space:pre">                                        </span>render: [ :html | </div><div><span class="Apple-tab-span" style="white-space:pre">                                                </span>html script: 'parent.parent.window.location.replace("', renderContinuation registerForUrl greaseString, '")' ] )] ].</div>
<div><br></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>shouldDebug ifTrue: [ </div><div><span class="Apple-tab-span" style="white-space:pre">                </span>GRPlatform current openDebuggerOn: ex ]</div>
</div><div><br></div><div>Explanation:</div><div><br></div><div>#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:</div>
<div><br></div><div> shouldDebug ifTrue: [ GRPlatform current openDebuggerOn: ex ]</div><div><br></div><div>As the state has been restored we can open a debugger on the exception and debug the original problem.</div><div>
<br></div><div>For comparison, our first implementation captured the continuation explicitly, though we decided the above solution was neater:</div><div><br></div><div>the lines:</div><div><br></div><div><div> shouldDebug := self session presenter call: (WAWalkback current exception: ex) ]</div>
<div>on: WARenderNotification </div><div>do: [ :exDontCare |</div></div><div><br></div><div>where replaced by:</div><div><br></div><div><div>shouldDebug := GRPlatform current seasideSuspendFlowDo: [ :cc |</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>session presenter show: (WAWalkback current exception: ex) onAnswer: [:answer | cc value: answer ].</div>
</div><div><br></div><div>with the call to self requestContext respond: [...] inside the #seasideSuspendFlowDo:</div><div><br></div><div>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.</div>
<div><br></div><div>I hope I haven't made the explanation more confusing than the code....</div><div><br></div><div>Nick</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div class="gmail_quote"><div><div></div><div class="h5">On Tue, Aug 30, 2011 at 10:05 AM, Nick Ager <span dir="ltr"><<a href="mailto:nick.ager@gmail.com" target="_blank">nick.ager@gmail.com</a>></span> wrote:<br>
</div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div></div><div class="h5">Hi,<div><br></div><div>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.</div>
<div><br></div><div>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:</div>
<div><br></div><div><div>handleException: ex</div><div><span style="white-space:pre-wrap">        </span>| session requestContext key continuation renderContinuation |</div><div><span style="white-space:pre-wrap">        </span>requestContext := self requestContext.</div>
<div><span style="white-space:pre-wrap">        </span>session := requestContext session.</div><div><span style="white-space:pre-wrap">        </span>key := requestContext request fields at: session actionField.</div>
<div><span style="white-space:pre-wrap">        </span>continuation := session continuations at: key.</div><div><span style="white-space:pre-wrap">        </span>renderContinuation := continuation createRenderContinuation.</div>
<div><span style="white-space:pre-wrap">        </span>session presenter show: (WAWalkback current exception: ex) onAnswer: [:answer | </div><div><span style="white-space:pre-wrap">                </span>answer ifTrue: [ </div>
<div><span style="white-space:pre-wrap">                        </span>self flag: #todo. "work out why I get the error: 'Error: context not in self'"</div><div><span style="white-space:pre-wrap">                        </span>GRPlatform current openDebuggerOn: ex ] ].</div>
<div><br></div><div><span style="white-space:pre-wrap">        </span>"redirect the main page to the error location"</div><div><span style="white-space:pre-wrap">        </span>self requestContext respond: </div>
<div><span style="white-space:pre-wrap">                </span>[ :response | </div><div><span style="white-space:pre-wrap">                </span>response</div><div><span style="white-space:pre-wrap">                        </span>contentType: WAMimeType textHtml;</div>
<div><span style="white-space:pre-wrap">                        </span>nextPutAll: (WARenderCanvas builder</div><div><span style="white-space:pre-wrap">                                </span>fullDocument: true;</div><div><span style="white-space:pre-wrap">                                </span>scriptGeneratorClass: JQScriptGenerator; "removes the onload from body"</div>
<div><span style="white-space:pre-wrap">                                </span>render: [ :html | </div><div><span style="white-space:pre-wrap">                                        </span>html script: 'parent.parent.window.location.replace("', renderContinuation registerForUrl greaseString, '")' ] )]</div>
</div><div><br></div><div>I've a horrible feeling I'm missing an obvious, simpler solution</div><div><br></div><div>Thanks,</div><div><br></div><font color="#888888"><div>Nick</div>
</font><br></div></div>_______________________________________________<br>
seaside mailing list<br>
<a href="mailto:seaside@lists.squeakfoundation.org" target="_blank">seaside@lists.squeakfoundation.org</a><br>
<a href="http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside" target="_blank">http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside</a><br>
<br></blockquote></div><br>
<br>_______________________________________________<br>
seaside mailing list<br>
<a href="mailto:seaside@lists.squeakfoundation.org">seaside@lists.squeakfoundation.org</a><br>
<a href="http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside" target="_blank">http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside</a><br>
<br></blockquote></div><br>