Improve error handling
gitile/handler.scm
33 | 33 | ||
34 | 34 | (define (not-found request) | |
35 | 35 | (format #t "Not found: ~a~%" (uri->string (request-uri request))) | |
36 | - | (values (build-response #:code 404) | |
37 | - | (string-append "Resource not found: " | |
38 | - | (uri->string (request-uri request))))) | |
36 | + | (show (style `((p "Resource not found: " | |
37 | + | ,(uri->string (request-uri request)))) | |
38 | + | "" ""))) | |
39 | 39 | ||
40 | 40 | (define (style page project ref) | |
41 | 41 | `(html | |
… | |||
58 | 58 | ,@page) | |
59 | 59 | (footer (p (a (@ (href "https://lepiller.eu")) "Who am I?")))))) | |
60 | 60 | ||
61 | - | (define (show page) | |
62 | - | (values '((content-type . (text/html))) | |
61 | + | (define* (show page #:key (code 200)) | |
62 | + | (values (build-response #:code code #:headers '((content-type . (text/html)))) | |
63 | 63 | (with-output-to-string (lambda _ (sxml->xml page))))) | |
64 | 64 | ||
65 | 65 | (define (show-raw page) | |
… | |||
67 | 67 | page)) | |
68 | 68 | ||
69 | 69 | (define (gitile-handler config) | |
70 | - | (define (get-repo name) | |
71 | - | (let ((repo (string-append (config-repositories config) | |
72 | - | "/" name ".git"))) | |
73 | - | (pk 'repo repo) | |
74 | - | (pk 'exists (file-exists? (string-append repo "/git-daemon-export-ok"))) | |
75 | - | (if (file-exists? (string-append repo "/git-daemon-export-ok")) | |
76 | - | (repository-open repo) | |
77 | - | #f))) | |
78 | - | ||
70 | + | (define (call-with-repo project-name callback) | |
71 | + | (define (repo-404 content project-name ref) | |
72 | + | (show (style content project-name ref) | |
73 | + | #:code 404)) | |
74 | + | (define (repo-500 content) | |
75 | + | (show content #:code 500)) | |
76 | + | (define (get-repo name) | |
77 | + | (let ((repo (string-append (config-repositories config) | |
78 | + | "/" name ".git"))) | |
79 | + | (pk 'repo repo) | |
80 | + | (pk 'exists (file-exists? (string-append repo "/git-daemon-export-ok"))) | |
81 | + | (if (file-exists? (string-append repo "/git-daemon-export-ok")) | |
82 | + | (repository-open repo) | |
83 | + | #f))) | |
84 | + | ||
85 | + | (let ((repo (get-repo project-name))) | |
86 | + | (if repo | |
87 | + | (catch #t | |
88 | + | (lambda _ | |
89 | + | (callback repo)) | |
90 | + | (lambda* (key . args) | |
91 | + | (match key | |
92 | + | ('not-found | |
93 | + | (pk 'except key args) | |
94 | + | (repo-404 (assoc-ref args 'content) | |
95 | + | project-name | |
96 | + | (or (assoc-ref args 'ref) "-"))) | |
97 | + | (_ | |
98 | + | (pk 'uncaught-exception key args) | |
99 | + | (repo-500 `((p "Internal error"))))))) | |
100 | + | (repo-404 `((p "Repository not found: " ,project-name)) project-name | |
101 | + | "-")))) | |
79 | 102 | (match config | |
80 | 103 | (($ <config> port host database repositories) | |
81 | 104 | (lambda (request body) | |
… | |||
83 | 106 | (pk 'body (if body (utf8->string body) body)) | |
84 | 107 | (match (request-path-components request) | |
85 | 108 | ((project-name) | |
86 | - | (show (style (project-index project-name (get-repo project-name)) | |
87 | - | project-name "-"))) | |
109 | + | (call-with-repo project-name | |
110 | + | (lambda (repo) | |
111 | + | (show (style (project-index project-name repo) | |
112 | + | project-name "-"))))) | |
88 | 113 | ((project-name "tree" ref path ...) | |
89 | - | (show (style (project-files project-name (get-repo project-name) | |
90 | - | #:ref ref #:path path) | |
91 | - | project-name ref))) | |
114 | + | (call-with-repo project-name | |
115 | + | (lambda (repo) | |
116 | + | (show (style (project-files project-name repo #:ref ref #:path path) | |
117 | + | project-name ref))))) | |
92 | 118 | ((project-name "raw" ref path ...) | |
93 | - | (show-raw (project-file-raw (get-repo project-name) path #:ref ref))) | |
119 | + | (call-with-repo project-name | |
120 | + | (lambda (repo) | |
121 | + | (show-raw (project-file-raw repo path #:ref ref))))) | |
94 | 122 | ((project-name "commits") | |
95 | - | (show (style (project-commits project-name (get-repo project-name) #f) | |
96 | - | project-name "-"))) | |
123 | + | (call-with-repo project-name | |
124 | + | (lambda (repo) | |
125 | + | (show (style (project-commits project-name repo #f) | |
126 | + | project-name "-"))))) | |
97 | 127 | ((project-name "commits" ref) | |
98 | - | (show (style (project-commits project-name (get-repo project-name) ref) | |
99 | - | project-name ref))) | |
128 | + | (call-with-repo project-name | |
129 | + | (lambda (repo) | |
130 | + | (show (style (project-commits project-name repo ref) | |
131 | + | project-name ref))))) | |
100 | 132 | ((project-name "commit" ref) | |
101 | - | (show (style (project-commit project-name (get-repo project-name) ref) | |
102 | - | project-name ref))) | |
133 | + | (call-with-repo project-name | |
134 | + | (lambda (repo) | |
135 | + | (show (style (project-commit project-name repo ref) | |
136 | + | project-name ref))))) | |
103 | 137 | ((project-name "tags") | |
104 | - | (show (style (project-tags project-name (get-repo project-name)) | |
105 | - | project-name "-"))) | |
106 | - | (_ (not-found request))))))) | |
138 | + | (call-with-repo project-name | |
139 | + | (lambda (repo) | |
140 | + | (show (style (project-tags project-name repo) | |
141 | + | project-name "-"))))) | |
142 | + | (_ (not-found request))))))) |
gitile/repo.scm
58 | 58 | repo)) | |
59 | 59 | ||
60 | 60 | (define (ref->oid repo ref) | |
61 | - | (let ((ref-name (or ref | |
62 | - | (false-if-exception (reference-name (repository-head repo)))))) | |
63 | - | (or (false-if-exception (string->oid ref-name)) | |
64 | - | (false-if-exception (reference-name->oid repo ref-name)) | |
65 | - | (reference-name->oid repo (search-reference repo ref-name))))) | |
61 | + | (define (ref->oid* repo ref) | |
62 | + | (let ((ref-name (or ref | |
63 | + | (false-if-exception (reference-name (repository-head repo)))))) | |
64 | + | (or (false-if-exception (string->oid ref-name)) | |
65 | + | (false-if-exception (reference-name->oid repo ref-name)) | |
66 | + | (false-if-exception (reference-name->oid repo (search-reference repo ref-name)))))) | |
67 | + | (or (ref->oid* repo ref) | |
68 | + | (throw 'not-found | |
69 | + | `(content ((p "Ref not found in repository: " ,ref))) | |
70 | + | `(ref ,ref)))) | |
66 | 71 | ||
67 | 72 | (define-record-type <file> | |
68 | 73 | (make-file name type commit) | |
… | |||
98 | 103 | (let* ((oid (ref->oid repo ref)) | |
99 | 104 | (commit (commit-lookup repo oid)) | |
100 | 105 | (tree (commit-tree commit)) | |
101 | - | (entry (tree-entry-bypath tree path)) | |
102 | - | (entry-oid (tree-entry-id entry)) | |
103 | - | (blob (blob-lookup repo entry-oid))) | |
104 | - | (blob-content blob))) | |
106 | + | (entry (false-if-exception (tree-entry-bypath tree path)))) | |
107 | + | (if entry | |
108 | + | (let* ((entry-oid (tree-entry-id entry)) | |
109 | + | (blob (blob-lookup repo entry-oid))) | |
110 | + | (blob-content blob)) | |
111 | + | (throw 'not-found | |
112 | + | `(content ((p "path not found in repository for this commit: " ,path))) | |
113 | + | `(ref ,ref))))) | |
105 | 114 | ||
106 | 115 | (define (last-commit-for-file path commit) | |
107 | 116 | (let* ((initial-tree (commit-tree commit)) | |
… | |||
146 | 155 | ||
147 | 156 | (define (get-commit repo hash) | |
148 | 157 | (let* ((oid (ref->oid repo hash)) | |
149 | - | (commit (commit-lookup repo oid))) | |
150 | - | commit)) | |
158 | + | (commit (false-if-exception (commit-lookup repo oid)))) | |
159 | + | (or commit | |
160 | + | (throw 'not-found | |
161 | + | `(content ((p "Commit not found in this repository: " ,hash))) | |
162 | + | `(ref ,hash))))) |