
#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