-
Notifications
You must be signed in to change notification settings - Fork 146
Expand file tree
/
Copy pathexception.clj
More file actions
84 lines (71 loc) · 2.76 KB
/
exception.clj
File metadata and controls
84 lines (71 loc) · 2.76 KB
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
(ns compojure.api.exception
(:require [ring.util.http-response :as response]
[clojure.walk :as walk]
[compojure.api.impl.logging :as logging]
[schema.utils :as su])
(:import [schema.utils ValidationError NamedError]
[com.fasterxml.jackson.core JsonParseException]
[org.yaml.snakeyaml.parser ParserException]))
;;
;; Default exception handlers
;;
(defn safe-handler
"Writes :error to log with the exception message & stacktrace.
Error response only contains class of the Exception so that it won't accidentally
expose secret details."
[^Exception e data req]
(logging/log! :error e (.getMessage e))
(response/internal-server-error {:type "unknown-exception"
:class (.getName (.getClass e))}))
(defn stringify-error
"Stringifies symbols and validation errors in Schema error, keeping the structure intact."
[error]
(walk/postwalk
(fn [x]
(cond
(instance? ValidationError x) (str (su/validation-error-explain x))
(instance? NamedError x) (str (su/named-error-explain x))
:else x))
error))
(defn response-validation-handler
"Creates error response based on Schema error."
[e data req]
(response/internal-server-error {:errors (stringify-error (su/error-val data))}))
(defn request-validation-handler
"Creates error response based on Schema error."
[e data req]
(response/bad-request {:errors (stringify-error (su/error-val data))}))
(defn http-response-handler
"reads response from ex-data :response"
[_ {:keys [response]} _]
response)
(defn schema-error-handler
"Creates error response based on Schema error."
[e data req]
; FIXME: Why error is not wrapped to ErrorContainer here?
(response/bad-request {:errors (stringify-error (:error data))}))
(defn request-parsing-handler
[^Exception ex data req]
(let [cause (.getCause ex)]
(response/bad-request {:type (cond
(instance? JsonParseException cause) "json-parse-exception"
(instance? ParserException cause) "yaml-parse-exception"
:else "parse-exception")
:message (.getMessage cause)})))
;;
;; Logging
;;
(defn with-logging
"Wrap compojure-api exception-handler a function which will log the
exception message and stack-trace with given log-level."
([handler] (with-logging handler :error))
([handler log-level]
{:pre [(#{:trace :debug :info :warn :error :fatal} log-level)]}
(fn [^Exception e data req]
(logging/log! log-level e (.getMessage e))
(handler e data req))))
;;
;; Mappings from other Exception types to our base types
;;
(def legacy-exception-types
{:ring.swagger.schema/validation ::request-validation})