Catch and Throw

Started by dukester, August 30, 2007, 06:09:03 AM

Previous topic - Next topic

dukester

hey...



given the following snippet:



(catch

 (for (i 0 9)

   (if (= i 5)

     (throw (string "i was " i ))

   )

   

   (print i " ")

 )

)



How do I get the "throw" message to appear on my screen?



I tried:



(println (throw (string "i was " i )))



with no success. TIA...
duke

Jeff

#1
You need to catch the expression into a symbol:


> (catch (for (i 0 9) (if (= i 5) (throw (string "i was " i)))) 'foo)
true
> foo
"i was 5"
>


The catch expression will return true if the expression did not throw an error (either a system error or a user error (using throw-error instead of throw)) or nil if it did.  It will set 'foo to the result of the evaluated expression.
Jeff

=====

Old programmers don\'t die. They just parse on...



http://artfulcode.net\">Artful code

Lutz

#2
dukester's method, without without the result variable works too, the return value thrown is then the return value of the whole 'catch expression:


(println (catch
(for (i 0 9)
(if (= i 5)
(throw (string "i was " i )))
(print i " "))
))

0 1 2 3 4 i was 5
"i was 5"


Note that "i was 5" appears twice, first from the 'println surrrounding the whole 'catch statement, second as the return value of it all.



You need the additional symbol parameter in 'catch only when wanting to 'catch errors, if using 'catch purely for flow control the above method is valid too.



See also here: http://newlisp.org/CodePatterns.html">http://newlisp.org/CodePatterns.html the chapters 7. and 8.



Lutz

Jeff

#3
I also wrote a tutorial on using catch/throw for error handling here:



http://artfulcode.nfshost.com/files/simple-error-handling-in-newlisp.html">//http://artfulcode.nfshost.com/files/simple-error-handling-in-newlisp.html
Jeff

=====

Old programmers don\'t die. They just parse on...



http://artfulcode.net\">Artful code

dukester

#4
Quote from: "Jeff"I also wrote a tutorial on using catch/throw for error handling here:



http://artfulcode.nfshost.com/files/simple-error-handling-in-newlisp.html">//http://artfulcode.nfshost.com/files/simple-error-handling-in-newlisp.html


Thank you! I'm on it!
duke

dukester

#5
Quote from: "Lutz"dukester's method, without without the result variable works too, the return value thrown is then the return value of the whole 'catch expression:


(println (catch
(for (i 0 9)
(if (= i 5)
(throw (string "i was " i )))
(print i " "))
))

0 1 2 3 4 i was 5
"i was 5"


Note that "i was 5" appears twice, first from the 'println surrrounding the whole 'catch statement, second as the return value of it all.



You need the additional symbol parameter in 'catch only when wanting to 'catch errors, if using 'catch purely for flow control the above method is valid too.



See also here: http://newlisp.org/CodePatterns.html">http://newlisp.org/CodePatterns.html the chapters 7. and 8.



Lutz


Thanks Lutz!



My setup must be wrong. I'm using the Textpad editor and run the scripts from within Textpad. Here's the output:



0 1 2 3 4

Tool completed with exit code 1



It never prints out the "throw" message.
duke

Jeff

#6
When running from the repl (the newlisp interpreter at the commandline, not as a script like textpad does), the interpreter will echo back the value of the last evaluated expression.  So if you typed 1 into the repl, it would go like:


> 1
1
>


The value of a println expression is the string it prints, so:


> (println "Hello world")
Hello world
"Hello world"
>
Jeff

=====

Old programmers don\'t die. They just parse on...



http://artfulcode.net\">Artful code

dukester

#7
Quote from: "Jeff"When running from the repl (the newlisp interpreter at the commandline, not as a script like textpad does), the interpreter will echo back the value of the last evaluated expression.  So if you typed 1 into the repl, it would go like:



[snip]



OK! I got the code to work from the REPL!  So tell me, if I'm writing a CGI script and I want to "catch" an event -- say an error -- and if and when the event occurs, "throw" a [debug] message to the screen. Am I understanding correctly that this cannot be done using the catch/throw duo?
duke

Jeff

#8
Yes, it can.  However, there is a more useful function for catching all cgi type errors- error-event.  You can specify a function/lambda that handles all errors, which can be read using error-text or error-number.  This includes using throw-error from user-defined functions.



The alternative is to thread error handling throughout the code like Java or Python.  The equivalent to a try/except statement, including using error-event:


(error-event
  (fn ()
    (print "Content-type: text/htmlnn")
    (println "<p>" (error-text) "</p>")))

(if (catch (perform-some-db-op) 'foo)
  (continue-with-page-load)
  (throw-error "controlled error message"))


The cgi.lsp library provided by Lutz already does this- it takes error events (script errors) and prints them to the browser window.  Obviously, this should be overridden in a production app, but for development it's helpful.  Just make sure that cgi.lsp is loaded before anything else to make sure that any errors get handled.
Jeff

=====

Old programmers don\'t die. They just parse on...



http://artfulcode.net\">Artful code

dukester

#9
Thanks Jeff for the info...



I seem to be getting confused with newLISP's various behaviors, depending on whether or not one is working from the REPL or not. It's something that I'll have to get familiar and comfortable with.
duke

Jeff

#10
Using an editor that can evaluate the buffer can help.  I use textmate and can just hit command-r to evaluate the file and see the output as html.  That doesn't help with cgi, of course, because the cgi env vars are not available- for that I use a browser and MAMP with cgi turned on.
Jeff

=====

Old programmers don\'t die. They just parse on...



http://artfulcode.net\">Artful code

dukester

#11
I'm suspect that what you are referring to in `textmate' is available as well in the TextPad editor that I'm using. One command sends the file to newLISP for processing. The results are output to "Command Results" file immediately viewable in TextPad.  Sounds pretty much the same as textmate, no?
duke

Jeff

#12
Yes.  That way you only get output that you print in your code.  Scite has a similar feature as well.
Jeff

=====

Old programmers don\'t die. They just parse on...



http://artfulcode.net\">Artful code

dukester

#13
You bet! I've used `scite' as well. To summarize, I've learned that _some_ newLISP behavior is only evident when the code is run directly in the REPL. For example, the catch/throw messages. So if I use catch/throw in a script, I have to do in such a way as to not depend on the output message being viewable -- i.e. I should merely _test_ for it. Am I close?
duke