diff --git a/guix/gexp.scm b/guix/gexp.scm index 1b8e43e99..80d8f735b 100644 --- a/guix/gexp.scm +++ b/guix/gexp.scm @@ -26,6 +26,8 @@ #:use-module (srfi srfi-9) #:use-module (srfi srfi-9 gnu) #:use-module (srfi srfi-26) + #:use-module (srfi srfi-34) + #:use-module (srfi srfi-35) #:use-module (ice-9 match) #:export (gexp gexp? @@ -84,7 +86,13 @@ gexp-compiler? lower-object - lower-inputs)) + lower-inputs + + &gexp-error + gexp-error? + &gexp-input-error + gexp-input-error? + gexp-error-invalid-input)) ;;; Commentary: ;;; @@ -140,6 +148,14 @@ (lower gexp-compiler-lower) (expand gexp-compiler-expand)) ;#f | DRV -> sexp +(define-condition-type &gexp-error &error + gexp-error?) + +(define-condition-type &gexp-input-error &gexp-error + gexp-input-error? + (input gexp-error-invalid-input)) + + (define %gexp-compilers ;; 'eq?' mapping of record type descriptor to . (make-hash-table 20)) @@ -177,8 +193,11 @@ procedure to expand it; otherwise return #f." corresponding to OBJ for SYSTEM, cross-compiling for TARGET if TARGET is true. OBJ must be an object that has an associated gexp compiler, such as a ." - (let ((lower (lookup-compiler obj))) - (lower obj system target))) + (match (lookup-compiler obj) + (#f + (raise (condition (&gexp-input-error (input obj))))) + (lower + (lower obj system target)))) (define-syntax define-gexp-compiler (syntax-rules (=> compiler expander) diff --git a/guix/packages.scm b/guix/packages.scm index 61171b834..d865dd5ad 100644 --- a/guix/packages.scm +++ b/guix/packages.scm @@ -31,7 +31,6 @@ #:use-module (guix memoization) #:use-module (guix build-system) #:use-module (guix search-paths) - #:use-module (guix gexp) #:use-module (guix sets) #:use-module (ice-9 match) #:use-module (ice-9 vlist) @@ -1226,4 +1225,7 @@ outside of the store) or SOURCE itself (if SOURCE is already a store item.)" ((? string? file) (add-to-store store (basename file) #t "sha256" file)) (_ + ;; XXX: 'lower' can throw '&gexp-input-error'. From a UI viewpoint, + ;; this is better than a wrong-type-arg error, but it's not ideal + ;; because gexps don't have source location information yet. (lower store source system)))))) diff --git a/guix/ui.scm b/guix/ui.scm index 345bf490b..b3c94795f 100644 --- a/guix/ui.scm +++ b/guix/ui.scm @@ -26,6 +26,7 @@ ;;; along with GNU Guix. If not, see . (define-module (guix ui) + #:use-module (guix gexp) #:use-module (guix utils) #:use-module (guix store) #:use-module (guix config) @@ -448,6 +449,10 @@ interpreted." (location->string loc) (package-full-name package) (build-system-name system)))) + ((gexp-input-error? c) + (let ((input (package-error-invalid-input c))) + (leave (_ "~s: invalid G-expression input~%") + (gexp-error-invalid-input c)))) ((profile-not-found-error? c) (leave (_ "profile '~a' does not exist~%") (profile-error-profile c)))