Catch and Throw

For the Compleat Fan
Locked
dukester
Posts: 115
Joined: Tue May 08, 2007 1:06 pm
Location: Alberta, Canada

Catch and Throw

Post by 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...

Jeff
Posts: 604
Joined: Sat Apr 07, 2007 2:23 pm
Location: Ohio
Contact:

Post by Jeff »

You need to catch the expression into a symbol:

Code: Select all

> (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...

Artful code

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Post by 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:

Code: Select all

(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 the chapters 7. and 8.

Lutz

Jeff
Posts: 604
Joined: Sat Apr 07, 2007 2:23 pm
Location: Ohio
Contact:

Post by Jeff »

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

http://artfulcode.nfshost.com/files/sim ... wlisp.html
Jeff
=====
Old programmers don't die. They just parse on...

Artful code

dukester
Posts: 115
Joined: Tue May 08, 2007 1:06 pm
Location: Alberta, Canada

Post by dukester »

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

http://artfulcode.nfshost.com/files/sim ... wlisp.html
Thank you! I'm on it!

dukester
Posts: 115
Joined: Tue May 08, 2007 1:06 pm
Location: Alberta, Canada

Post by dukester »

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

Code: Select all

(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 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.

Jeff
Posts: 604
Joined: Sat Apr 07, 2007 2:23 pm
Location: Ohio
Contact:

Post by 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:

Code: Select all

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

Code: Select all

> (println "Hello world")
Hello world
"Hello world"
>
Jeff
=====
Old programmers don't die. They just parse on...

Artful code

dukester
Posts: 115
Joined: Tue May 08, 2007 1:06 pm
Location: Alberta, Canada

Post by dukester »

[quote="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?

Jeff
Posts: 604
Joined: Sat Apr 07, 2007 2:23 pm
Location: Ohio
Contact:

Post by Jeff »

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:

Code: Select all

(error-event
  (fn ()
    (print "Content-type: text/html\n\n")
    (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...

Artful code

dukester
Posts: 115
Joined: Tue May 08, 2007 1:06 pm
Location: Alberta, Canada

Post by dukester »

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.

Jeff
Posts: 604
Joined: Sat Apr 07, 2007 2:23 pm
Location: Ohio
Contact:

Post by Jeff »

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...

Artful code

dukester
Posts: 115
Joined: Tue May 08, 2007 1:06 pm
Location: Alberta, Canada

Post by dukester »

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?

Jeff
Posts: 604
Joined: Sat Apr 07, 2007 2:23 pm
Location: Ohio
Contact:

Post by Jeff »

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...

Artful code

dukester
Posts: 115
Joined: Tue May 08, 2007 1:06 pm
Location: Alberta, Canada

Post by dukester »

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?

Locked