[Seaside] mailing stack trace
Nevin Pratt
nevin at smalltalkpro.com
Tue May 27 17:11:13 CEST 2003
Derek Brans wrote:
> Nevin,
>
> Could you post the code for emailing yourself a stack trace in the
> event of an error?
>
> Thank you.
>
Yes. But it's ugly.
First, in my custom subclass of WASession (which I call BBSession), I
have this:
******
handleError: e
| str |
e initialContext: e initialContext copyStack.
[str _ ReadWriteStream on: String new.
str nextPutAll: 'Date: ' , MailMessage dateStampNow , '
From: support at bountifulbaby.com
Subject: Stack Walkback
To: nevin at smalltalkpro.com
'.
self printWalkbackOn: str for: e.
(AdHocComposition celeste: 'server' initialText: str contents) submit]
on: Error
do: [:ex | ex].
self
returnResponse: (WAResponse forwardTo: '/seaside/index')
*******
However, you will notice issues right off the bat:
1. 'support at bountifulbaby.com' is hardcoded. PLEASE use something
else!!! :-)
2. 'nevin at smalltalkpro.com' is hardcoded. PLEASE use something else!!! :-)
3. 'server' is hardcoded, which happens to resolve to the machine name
to send the email through. Again, you will *have* to use something else
for your particular installation, as I doubt your machine knows which
machine the 'server' machine is :-).
4. The final action (forwarding to '/seaside/index') is hardcoded.
Again, you will want something particular for your installation.
5. The way I let AdHocComposition>>celeste: handle the mail isn't the
clearest/cleanest. I've seen cleaner code elsewhere for sending emails.
But, the above works.
Obviously a better solution would be to refactor and redesign so that
this stuff isn't hardcoded.
Now on to the next step:
My #printWalkbackOn:for: method (used from the above method) is:
*******
printWalkbackOn: aStream for: exception
| context |
aStream nextPut: Character cr.
aStream nextPutAll: '<h1>'.
aStream nextPut: Character cr.
aStream nextPutAll: exception description.
aStream nextPut: Character cr.
aStream nextPutAll: '</h1>'.
aStream nextPut: Character cr.
aStream nextPutAll: '<ul>'.
context _ thisContext.
8
timesRepeat: [context _ context sender].
[context notNil]
whileTrue: [self printStackFrame: context on: aStream.
context _ context sender].
aStream nextPutAll: '</ul>'.
aStream nextPutAll: '</table>'
********
Again, there are issues:
1. I only go 8 levels deep in the stack, and this is again hardcoded.
2. The embedded html could be done cleaner.
Now on to the next step, the #printStackFrame:on: method that the above
method uses:
********
printStackFrame: aContext on: aStream
aStream nextPutAll: '<li>';
nextPutAll: aContext fullPrintString.
aStream nextPut: Character cr.
aStream nextPutAll: '<blockquote>'.
aStream nextPut: Character cr.
aStream nextPutAll: '<table border="1">'.
aStream nextPut: Character cr.
aStream nextPutAll: '<tr>'.
aStream nextPut: Character cr.
aStream nextPutAll: '<td>self</td>'.
aStream nextPut: Character cr.
aStream nextPutAll: '<td>'.
aStream nextPut: Character cr.
aStream
nextPutAll: (aContext receiver printStringLimitedTo: 70).
aStream nextPut: Character cr.
aStream nextPutAll: '</td>'.
aStream nextPut: Character cr.
aStream nextPutAll: '</tr>'.
aContext tempNames
doWithIndex: [:name :index |
aStream nextPut: Character cr.
aStream nextPutAll: '<tr><td>'.
aStream nextPutAll: name.
aStream nextPut: Character cr.
aStream nextPutAll: '</td>'.
aStream nextPut: Character cr.
aStream nextPutAll: '<td>'.
aStream
nextPutAll: ((aContext tempAt: index)
printStringLimitedTo: 70).
aStream nextPut: Character cr.
aStream nextPutAll: '</td></tr>'].
aStream nextPut: Character cr.
aStream nextPutAll: '</table>'.
aStream nextPut: Character cr.
aStream nextPutAll: '</blockquote></li>'.
aStream nextPut: Character cr
*********
And again, some of the same issues crop up with this method.
In other words, the above was just a quick and dirty hack to get it
going for now, but it works for me. I have no idea when/if I'll ever
change it.
Nevin
More information about the Seaside
mailing list