aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Baines <mail@cbaines.net>2020-03-14 12:46:02 +0000
committerChristopher Baines <mail@cbaines.net>2020-03-14 12:46:02 +0000
commita03e1601deda589d5b11a8472438e6fe60c39666 (patch)
tree641a133f92115e6a8885c637b041c8ab88b3b065
parent33958eac792bffd1a0ce0e33fcdd2568954323e3 (diff)
downloaddata-service-a03e1601deda589d5b11a8472438e6fe60c39666.tar
data-service-a03e1601deda589d5b11a8472438e6fe60c39666.tar.gz
Improve handling of errors
Adjust the previously unused error page code, and start to use it. Only show the error if configured to do so, to avoid leaking secret information.
-rw-r--r--.envrc2
-rw-r--r--guix-data-service/web/controller.scm126
-rw-r--r--guix-data-service/web/view/html.scm14
-rw-r--r--scripts/guix-data-service.in14
4 files changed, 88 insertions, 68 deletions
diff --git a/.envrc b/.envrc
index 94e9705..7b32f77 100644
--- a/.envrc
+++ b/.envrc
@@ -8,6 +8,8 @@ export GUILE_LOAD_COMPILED_PATH="$PWD:$PWD/tests:$GUILE_LOAD_COMPILED_PATH"
export GUILE_LOAD_PATH="$PWD:$GUILE_LOAD_PATH"
export PATH="$PWD/scripts:$PATH"
+export GUIX_DATA_SERVICE_SHOW_ERROR_DETAILS=true
+
if [ -f .local.envrc ]; then
source_env .local.envrc
fi
diff --git a/guix-data-service/web/controller.scm b/guix-data-service/web/controller.scm
index 111c2e5..6fb24fd 100644
--- a/guix-data-service/web/controller.scm
+++ b/guix-data-service/web/controller.scm
@@ -25,6 +25,7 @@
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-11)
#:use-module (srfi srfi-26)
+ #:use-module (system repl error-handling)
#:use-module (web request)
#:use-module (web response)
#:use-module (web uri)
@@ -63,7 +64,8 @@
#:use-module (guix-data-service web compare controller)
#:use-module (guix-data-service web revision controller)
#:use-module (guix-data-service web repository controller)
- #:export (controller))
+ #:export (%show-error-details
+ controller))
(define cache-control-default-max-age
(* 60 60 24)) ; One day
@@ -78,19 +80,6 @@
target
(list functions ...)))
-(define (render-with-error-handling page message)
- (apply render-html (page))
- ;; (catch #t
- ;; (lambda ()
- ;; (receive (sxml headers)
- ;; (pretty-print (page))
- ;; (render-html sxml headers)))
- ;; (lambda (key . args)
- ;; (format #t "ERROR: ~a ~a\n"
- ;; key args)
- ;; (render-html (error-page message))))
- )
-
(define (render-derivation conn derivation-file-name)
(let ((derivation (select-derivation-by-file-name conn
derivation-file-name)))
@@ -193,57 +182,70 @@
(static-asset-from-store-renderer)
render-static-asset))
+(define %show-error-details
+ (make-parameter #f))
+
(define (controller request method-and-path-components
mime-types body
secret-key-base)
- (match method-and-path-components
- (('GET "assets" rest ...)
- (or (handle-static-assets (string-join rest "/")
- (request-headers request))
- (not-found (request-uri request))))
- (('GET "healthcheck")
- (let ((database-status
- (catch
- #t
- (lambda ()
- (with-postgresql-connection
- "web healthcheck"
- (lambda (conn)
- (number?
- (string->number
- (first
- (count-guix-revisions conn)))))))
- (lambda (key . args)
- #f))))
- (render-json
- `((status . ,(if database-status
- "ok"
- "not ok")))
- #:code (if (eq? database-status
- #t)
- 200
- 500))))
- (('GET "README")
- (let ((filename (string-append (%config 'doc-dir) "/README.html")))
- (if (file-exists? filename)
- (render-html
- #:sxml (readme (call-with-input-file filename
- get-string-all)))
- (render-html
- #:sxml (general-not-found
- "README not found"
- "The README.html file does not exist")
- #:code 404))))
- (_
- (with-postgresql-connection
- "web"
- (lambda (conn)
- (controller-with-database-connection request
- method-and-path-components
- mime-types
- body
- conn
- secret-key-base))))))
+ (define (controller-thunk)
+ (match method-and-path-components
+ (('GET "assets" rest ...)
+ (or (handle-static-assets (string-join rest "/")
+ (request-headers request))
+ (not-found (request-uri request))))
+ (('GET "healthcheck")
+ (let ((database-status
+ (catch
+ #t
+ (lambda ()
+ (with-postgresql-connection
+ "web healthcheck"
+ (lambda (conn)
+ (number?
+ (string->number
+ (first
+ (count-guix-revisions conn)))))))
+ (lambda (key . args)
+ #f))))
+ (render-json
+ `((status . ,(if database-status
+ "ok"
+ "not ok")))
+ #:code (if (eq? database-status
+ #t)
+ 200
+ 500))))
+ (('GET "README")
+ (let ((filename (string-append (%config 'doc-dir) "/README.html")))
+ (if (file-exists? filename)
+ (render-html
+ #:sxml (readme (call-with-input-file filename
+ get-string-all)))
+ (render-html
+ #:sxml (general-not-found
+ "README not found"
+ "The README.html file does not exist")
+ #:code 404))))
+ (_
+ (with-postgresql-connection
+ "web"
+ (lambda (conn)
+ (controller-with-database-connection request
+ method-and-path-components
+ mime-types
+ body
+ conn
+ secret-key-base))))))
+ (call-with-error-handling
+ controller-thunk
+ #:on-error 'backtrace
+ #:post-error (lambda args
+ (render-html #:sxml (error-page
+ (if (%show-error-details)
+ args
+ #f))
+ #:code 500))))
(define (controller-with-database-connection request
method-and-path-components
diff --git a/guix-data-service/web/view/html.scm b/guix-data-service/web/view/html.scm
index e45a67a..0f003ec 100644
--- a/guix-data-service/web/view/html.scm
+++ b/guix-data-service/web/view/html.scm
@@ -949,12 +949,16 @@
(h1 ,header-text)
(p ,body)))))
-(define (error-page message)
+(define* (error-page #:optional error)
(layout
#:body
`(,(header)
(div (@ (class "container"))
- (h1 "Error")
- (p "An error occurred. Sorry about that!")
- ,message
- (p (a (@ (href "/")) "Try something else?"))))))
+ (h1 "An error occurred")
+ (p "Sorry about that!")
+ ,@(if error
+ (match error
+ ((key . args)
+ `((b ,key)
+ (pre ,args))))
+ '())))))
diff --git a/scripts/guix-data-service.in b/scripts/guix-data-service.in
index 5822b52..b1946a5 100644
--- a/scripts/guix-data-service.in
+++ b/scripts/guix-data-service.in
@@ -25,12 +25,14 @@
(use-modules (srfi srfi-1)
(srfi srfi-37)
+ (ice-9 match)
(ice-9 textual-ports)
(system repl server)
(gcrypt pk-crypto)
(guix pki)
(guix-data-service config)
(guix-data-service web server)
+ (guix-data-service web controller)
(guix-data-service web nar controller))
(define %default-repl-server-port
@@ -68,6 +70,9 @@
(option '("update-database") #f #f
(lambda (opt name _ result)
(alist-cons 'update-database #t result)))
+ (option '("show-error-details") #f #f
+ (lambda (opt name _ result)
+ (alist-cons 'show-error-details #t result)))
(option '("port") #t #f
(lambda (opt name arg result)
(alist-cons 'port
@@ -86,6 +91,11 @@
(narinfo-signing-public-key . ,%public-key-file)
(narinfo-signing-private-key . ,%private-key-file)
(update-database . #f)
+ (show-error-details
+ . ,(match (getenv "GUIX_DATA_SERVICE_SHOW_ERROR_DETAILS")
+ (#f #f)
+ ("" #f)
+ (_ #t)))
(port . 8765)
(host . "0.0.0.0")))
@@ -170,7 +180,9 @@
key args)
(display "warning: not signing narinfo files\n"
(current-error-port))
- #f))))
+ #f)))
+ (%show-error-details
+ (assoc-ref opts 'show-error-details)))
(start-guix-data-service-web-server (assq-ref opts 'port)
(assq-ref opts 'host)