(* Copyright (C) 2001-2008 Henry Cejtin, Matthew Fluet, Suresh * Jagannathan, and Stephen Weeks. * * MLton is released under a BSD-style license. * See the file MLton-LICENSE for details. *) structure MLtonExn = struct open Primitive.MLton.Exn type t = exn val addExnMessager = General.addExnMessager val history: t -> string list = if keepHistory then (setExtendExtra (fn e => case e of NONE => SOME (MLtonCallStack.current ()) | SOME _ => e) ; (fn e => case extra e of NONE => [] | SOME cs => let (* Gets rid of the anonymous function passed to * setExtendExtra above. *) fun loop xs = case xs of [] => [] | x :: xs => if String.isPrefix "MLtonExn.fn " x then xs else loop xs in loop (MLtonCallStack.toStrings cs) end)) else fn _ => [] local val message = PrimitiveFFI.Stdio.print fun 'a wrapHandler (handler: exn -> unit) exn : 'a = (handler exn ; message "Top-level handler returned.\n" ; Exit.exit Exit.Status.failure) handle _ => (message "Top-level handler raised exception.\n" ; Exit.halt Exit.Status.failure ; raise Fail "MLton.Exn.wrapHandler") val defaultHandler = fn exn => (message (concat ["unhandled exception: ", exnMessage exn, "\n"]) ; (case history exn of [] => () | l => (message "with history:\n" ; List.app (fn s => message (concat ["\t", s, "\n"])) l)) ; Exit.exit Exit.Status.failure) in val getTopLevelHandler = Primitive.TopLevel.getHandler val setTopLevelHandler = Primitive.TopLevel.setHandler o wrapHandler fun 'a defaultTopLevelHandler (exn: exn): 'a = wrapHandler defaultHandler exn fun 'a topLevelHandler (exn: exn) : 'a = (getTopLevelHandler () exn ; raise Fail "MLton.Exn.topLevelHandler") end end