[GHC] #13372: Attach CallStack to IOError, add CallStack constraints to relevant functions in base

GHC ghc-devs at haskell.org
Sat Mar 4 00:36:39 UTC 2017


#13372: Attach CallStack to IOError, add CallStack constraints to relevant
functions in base
-------------------------------------+-------------------------------------
           Reporter:  ezyang         |             Owner:  (none)
               Type:  feature        |            Status:  new
  request                            |
           Priority:  normal         |         Milestone:
          Component:                 |           Version:  8.1
  libraries/base                     |
           Keywords:                 |  Operating System:  Unknown/Multiple
       Architecture:                 |   Type of failure:  None/Unknown
  Unknown/Multiple                   |
          Test Case:                 |        Blocked By:
           Blocking:                 |   Related Tickets:
Differential Rev(s):                 |         Wiki Page:
-------------------------------------+-------------------------------------
 In #12096 it is requested that we add CallStack to SomeException. This is
 a more conservative request for adding CallStack to IOError only. IOError
 is already an abstract data type, so it is a simple matter to augment it
 with space for a CallStack.

 The main design flex point is whether or not a `CallStack` should be
 associated with an IOError when it is constructed, or when it is thrown.
 There are pros and cons to both:

 1. If it is associated at construction time, the call stack will reflect
 when the IOError was constructed, not when it was thrown. This could be
 arbitrarily far away from the actual throw site. I've been mostly using
 CallStack for monadic code, and so my primary concern is with where in the
 monadic code the exception was thrown, so this info isn't really what I
 want.

 2. If it is associated at throw time, there are a few other problems.
 First, if someone uses throwIO rather than ioError, we won't actually
 associate a CallStack with the value. Second, if a user is rethrowing an
 exception, they may accidentally overwrite the old stack trace; but it was
 the original one that I wanted.

 For now, I suggest going with (1).

 Here is the proposal:

 * Add `ioeGetCallStack` and `ioeSetCallStack`, for setting and getting the
 `CallStack` recorded in `IOError`
 * `userError` and `mkIOError` gain a `HasCallStack` constraint. We have a
 choice for `annotateIOError`, but my suggestion is to NOT annotate it.
 * Let's annotate all functions that (transitively) may raise an IOError in
 base with `HasCallStack`.

 The primary benefit is now if I have a "file not found" exception or
 similar, I automatically get a stack trace saying exactly what code was
 run where the file was not found.

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13372>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list