# Finding the type of exception

**URL:** <https://racket.discourse.group/t/finding-the-type-of-exception/866>\
**Category:** Questions & Answers\
**Tags:** question, exceptions\
**Created:** [April 9, 2022, 2:10am UTC](https://racket.discourse.group/t/finding-the-type-of-exception/866 "2022-04-09T02:10:58Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![robertpostill](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/robertpostill/32/53_2.png) [@robertpostill](https://racket.discourse.group/u/robertpostill)\
**Post date:** [April 9, 2022, 2:10am UTC](https://racket.discourse.group/t/finding-the-type-of-exception/866/1 "2022-04-09T02:10:58Z")

</div>

When I'm writing around code that throws exceptions. Particularly when I'm going to wrap a side-effect in with-handlers I find myself often resorting to writing rackunit checks to find the exact type of exception being thrown. For example:

```scheme
(define (valid-json? data)
  (with-handlers ([exn:fail:read? (lambda (e) #f)])
    (with-input-from-string data (lambda () (read-json) #t))))
(module+ test
(test-case "it does not throw an exception for invalid json"
      (check-not-exn (lambda () (valid-json? "no JSON here")))))

```

This seems like a very haphazard and some cases difficult to realise strategy for working out what type of exception is being thrown.

Does anyone have superior techniques for understanding what exceptions could be thrown by code?

---

<div class="post-metadata">

**Author:** ![sorawee](https://avatars.discourse-cdn.com/v4/letter/s/ea5d25/32.png) [@sorawee](https://racket.discourse.group/u/sorawee)\
**Post date:** [April 9, 2022, 2:28am UTC](https://racket.discourse.group/t/finding-the-type-of-exception/866/2 "2022-04-09T02:28:01Z")

</div>

Would this work for you?

```scheme
#lang racket

(define (find-exn f)
  (with-handlers ([exn:fail? println]
                  ; you can change exn:fail? to (λ (e) #t) too,
                  ; but that might be too extreme
                  )
    (f)))

(find-exn (λ () (/ 1 0))) ;=> (exn:fail:contract:divide-by-zero "/: division by zero" #<continuation-mark-set>)
(find-exn (λ () (first '()))) ;=> (exn:fail:contract "first: contract violation\n expected: (and/c list? (not/c empty?))\n given: '()" #<continuation-mark-set>)

```

---

<div class="post-metadata">

**Author:** ![sschwarzer](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/sschwarzer/32/1940_2.png) [@sschwarzer](https://racket.discourse.group/u/sschwarzer)\
**Post date:** [April 10, 2022, 11:15am UTC](https://racket.discourse.group/t/finding-the-type-of-exception/866/3 "2022-04-10T11:15:35Z")

</div>

> [@robertpostill](#):
>
> Does anyone have superior techniques for understanding what exceptions could be thrown by code?

While @sorawee 's reply answers how to find more information about the exception from a specific invocation, I'm interested in the "could", that @robertpostill used. 🙂

Is there are way to find out what _could_ be raised? So far the only way I know is to thoroughly read the documentation (and maybe miss some exceptions that may be raised by a function that is called by the function I want to call 😉 ) So I wonder if there's a way to introspect code for which exceptions it may raise (directly or indirectly).

---

<div class="post-metadata">

**Author:** ![alexh](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/alexh/32/315_2.png) [@alexh](https://racket.discourse.group/u/alexh)\
**Post date:** [April 10, 2022, 12:07pm UTC](https://racket.discourse.group/t/finding-the-type-of-exception/866/4 "2022-04-10T12:07:28Z")

</div>

> [@sschwarzer](#):
>
> Is there are way to find out what _could_ be raised?

Exceptions are also raised for things which are ultimately program defects. For example, a division by zero will raise the `exn:fail:contract:divide-by-zero`:

```racket
(with-handlers ((exn:fail:contract:divide-by-zero? displayln)) 
  (/ 1 0))

```

Calling a function with the wrong number of arguments, trying to assign an undefined variable, reading outside the range of a vector, and several others situations will also raise exceptions. Any program which has defects can potentially raise exceptions.

In addition to this, user breaks (hitting Control C) will raise an `exn:break` exception at any time during execution, and this is outside the control of the developer.

So, I think that you can safely assume that any code can raise an exception from the `exn` hierarchy.

Alex.

---

<div class="post-metadata">

**Author:** ![ryanc](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/ryanc/32/71_2.png) [@ryanc](https://racket.discourse.group/u/ryanc)\
**Post date:** [April 10, 2022, 12:43pm UTC](https://racket.discourse.group/t/finding-the-type-of-exception/866/5 "2022-04-10T12:43:26Z")

</div>

> [@alexh](#):
>
> In addition to this, user breaks (hitting Control C) will raise an `exn:break` exception at any time during execution, and this is outside the control of the developer.

You can disable breaks for a thread can disable breaks by calling `(break-enabled #f)` or using `(parameterize-break #f <body>)`. Breaks are also automatically disabled in certain places, such as exception handlers (see `with-handlers`).

Of course, it's usually not a good idea to disable breaks for a long time (in the main thread, at least), so the point about `exn:break` still stands.

---

<div class="post-metadata">

**Author:** ![jbclements](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/jbclements/32/11_2.png) [@jbclements](https://racket.discourse.group/u/jbclements)\
**Post date:** [April 11, 2022, 5:43pm UTC](https://racket.discourse.group/t/finding-the-type-of-exception/866/6 "2022-04-11T17:43:16Z")

</div>

> [@alexh](#):
>
> So, I think that you can safely assume that any code can raise an exception from the `exn` hierarchy.

Was this intended to say that "any code can raise any exception from the `exn` hierarchy." ? I'm guessing that's what you meant, and I agree.

Of course, you could add a system like Java's, which—for a subset of exceptions—adds a static tracking mechanism to allow you to know exactly which exceptions could occur. That sounds to me like the kind of modification that would be delightfully impossible to bolt on to a dynamic language.

---

<div class="post-metadata">

**Author:** ![SamPhillips](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/samphillips/32/15_2.png) [@SamPhillips](https://racket.discourse.group/u/SamPhillips)\
**Post date:** [April 12, 2022, 1:12am UTC](https://racket.discourse.group/t/finding-the-type-of-exception/866/7 "2022-04-12T01:12:57Z")

</div>

Here is a naive hack static exception checker. To be remotely usable, it would still need a way of communicating the exceptions raised by a function and a library of exception signatures for existing standard library functions. Also, it would need to know about the exception hierarchy.

> <https://gist.github.com/samdphillips/b275477883d1ae1fa08c8cf031756460>
