basic exception handling

2011-01-24 Thread Ryan Waters
The following code doesn't catch the exception thrown like I think it
should.  Any recommendations appreciated.

https://gist.github.com/793340

Thank you,
Ryan

- - - -

(ns my-ns
  (:use [clj-time.core :only [date-time]]))

(defn my-date-time
  same as clj-time.core date-time but returns nil on improper input
  [ args]
  (try
(apply date-time (map #(Integer/parseInt %) args))
(catch NumberFormatException e hi)))

; works
(println (my-date-time 2011 01 01))

; errors out but should be caught in try/catch
(println (my-date-time 2011 asdf 01))


- - - - output


#DateTime 2011-01-01T00:00:00.000Z
Exception in thread main java.lang.RuntimeException:
java.lang.NumberFormatException: For input string: asdf (temp.clj:0)
at clojure.lang.Compiler.eval(Compiler.java:5440)
at clojure.lang.Compiler.load(Compiler.java:5857)
at clojure.lang.Compiler.loadFile(Compiler.java:5820)
at clojure.main$load_script.invoke(main.clj:221)
at clojure.main$script_opt.invoke(main.clj:273)
at clojure.main$main.doInvoke(main.clj:354)
at clojure.lang.RestFn.invoke(RestFn.java:437)
at clojure.lang.Var.invoke(Var.java:373)
at clojure.lang.AFn.applyToHelper(AFn.java:169)
at clojure.lang.Var.applyTo(Var.java:482)
at clojure.main.main(main.java:37)
Caused by: java.lang.RuntimeException:
java.lang.NumberFormatException: For input string: asdf
at clojure.lang.LazySeq.sval(LazySeq.java:47)
at clojure.lang.LazySeq.seq(LazySeq.java:56)
at clojure.lang.Cons.next(Cons.java:39)
at clojure.lang.RT.boundedLength(RT.java:1186)
at clojure.lang.AFn.applyToHelper(AFn.java:155)
at clojure.lang.AFn.applyTo(AFn.java:151)
at clojure.core$apply.invoke(core.clj:540)
at my_ns$my_date_time.doInvoke(temp.clj:8)
at clojure.lang.RestFn.invoke(RestFn.java:437)
at my_ns$eval64.invoke(temp.clj:13)
at clojure.lang.Compiler.eval(Compiler.java:5424)
... 10 more
Caused by: java.lang.NumberFormatException: For input string: asdf
at 
java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
at java.lang.Integer.parseInt(Integer.java:449)
at java.lang.Integer.parseInt(Integer.java:499)
at my_ns$my_date_time$fn__59.invoke(temp.clj:8)
at clojure.core$map$fn__3695.invoke(core.clj:2096)
at clojure.lang.LazySeq.sval(LazySeq.java:42)
... 20 more

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: basic exception handling

2011-01-24 Thread Ken Wesson
On Mon, Jan 24, 2011 at 10:32 AM, Ryan Waters ryan.or...@gmail.com wrote:
 The following code doesn't catch the exception thrown like I think it
 should.  Any recommendations appreciated.

 https://gist.github.com/793340

 Thank you,
 Ryan

 - - - -

 (ns my-ns
  (:use [clj-time.core :only [date-time]]))

 (defn my-date-time
  same as clj-time.core date-time but returns nil on improper input
  [ args]
  (try
    (apply date-time (map #(Integer/parseInt %) args))
    (catch NumberFormatException e hi)))

You're catching NumberFormatException.

 Exception in thread main java.lang.RuntimeException

but it's throwing a RuntimeException that wraps your NumberFormatException.

Unfortunately it's difficult to catch specific exceptions in Clojure
due to this wrapping. (I'm not sure why the wrapping is done; all the
invoke methods in IFn are declared with throws Exception so it seems
unnecessary.)

Usually you just catch Exception and, during debugging at least, log
the actual exception caught in case it wasn't what you expected -- for
instance, if you got an RTE wrapping an IndexOutOfBoundsException and
the expected exception types were NumberFormatException and
MalformedURLException, it would point to some screwy (nth v index)
usage or another bug.

If there is no function call boundary between the throw and catch, no
wrapping should occur, so

(let [url
  (try (URL. in-string)
(catch MalformedURLException _)))

should produce a URL object normally and nil on malformed input.

Another option in your case is to replace your #(Integer/parseInt %)
with a different function:

(defn get-int [str]
  (try (Integer/parseInt str)
(catch NumberFormatException _)))

This will return nil for malformed numbers. How date-time will respond
to nil inputs, I'm not sure, but you may want to be on the lookout for
NullPointerException in your outer, pre-existing catch. :)

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: basic exception handling

2011-01-24 Thread Ryan Waters
Thank you Ken - I should have checked for Exception; not sure why I
didn't.  Your other explanations were helpful too.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: basic exception handling

2011-01-24 Thread Ken Wesson
On Mon, Jan 24, 2011 at 2:19 PM, Ryan Waters ryan.or...@gmail.com wrote:
 Thank you Ken - I should have checked for Exception; not sure why I
 didn't.  Your other explanations were helpful too.

You're welcome.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en