-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathguile-conditions.scm
66 lines (59 loc) · 2.51 KB
/
guile-conditions.scm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
;;; ----------------------------------------------------------------------
;;; Copyright 2007-2008 Alexey Radul.
;;; ----------------------------------------------------------------------
;;; This file is part of Test Manager.
;;;
;;; Test Manager is free software; you can redistribute it and/or modify
;;; it under the terms of the GNU General Public License as published by
;;; the Free Software Foundation, either version 3 of the License, or
;;; (at your option) any later version.
;;;
;;; Test Manager is distributed in the hope that it will be useful,
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with Test Manager. If not, see <http://www.gnu.org/licenses/>.
;;; ----------------------------------------------------------------------
;;; I apologize to the reader for this horrible collection of hacks,
;;; but Guile appears to lack a condition system worth the name, so I
;;; am synthesizing one with exactly (read: only) the characteristics
;;; I need on top of catch-throw.
(define-record-type condition
(make-condition type throw-args continuation)
condition?
(type condition/type)
(throw-args condition/throw-args)
(continuation condition/continuation))
(define (condition/test-failure? condition)
(eq? 'test-failure (condition/type condition)))
(define (condition/error? condition)
(not (condition/test-failure? condition)))
(define (test-fail message)
(throw 'test-failure "test-fail" message #f))
(define (capture-unhandled-errors thunk)
"Run the given thunk. If it returns normally, return its return
value. If it signals an error, return an object representing that
error instead."
(let ((error-object #f))
(catch
#t
thunk
(lambda (key . args)
error-object)
(lambda (key . args)
(call-with-current-continuation
(lambda (thrown-at)
(set! error-object
(make-condition key args thrown-at))))))))
(define (write-condition-report condition port)
(define (extract-message throw-arguments)
;; TODO This relies on the arguments following Guile's throwing
;; convention.
(let ((message-template (cadr throw-arguments))
(template-parameters (caddr throw-arguments)))
(if template-parameters
(apply format #f message-template template-parameters)
message-template)))
(display (extract-message (condition/throw-args condition)) port))