1 | /*!
|
2 | * Copyright (c) 2017-2018 by The Funfix Project Developers.
|
3 | * Some rights reserved.
|
4 | *
|
5 | * Licensed under the Apache License, Version 2.0 (the "License");
|
6 | * you may not use this file except in compliance with the License.
|
7 | * You may obtain a copy of the License at
|
8 | *
|
9 | * http://www.apache.org/licenses/LICENSE-2.0
|
10 | *
|
11 | * Unless required by applicable law or agreed to in writing, software
|
12 | * distributed under the License is distributed on an "AS IS" BASIS,
|
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14 | * See the License for the specific language governing permissions and
|
15 | * limitations under the License.
|
16 | */
|
17 |
|
18 | /**
|
19 | * Type alias for errors that can be thrown.
|
20 | *
|
21 | * Since in JavaScript any object can be thrown, the standard
|
22 | * `Error` class (capital `E`) is not useful as a type in signatures,
|
23 | * the needed type being effectively `any`, but we still need a type
|
24 | * alias for documentation purposes.
|
25 | *
|
26 | * And since `any` represents an untyped object that bypasses the
|
27 | * type system, Funfix is using `Object` for TypeScript and `mixed`
|
28 | * for Flow to represent such throwables.
|
29 | */
|
30 | export type Throwable = Error | Object
|
31 |
|
32 | /**
|
33 | * A composite error represents a list of errors that were caught
|
34 | * while executing logic which delays re-throwing of errors.
|
35 | */
|
36 | export class CompositeError extends Error {
|
37 | private errorsRef: Array<Throwable>
|
38 |
|
39 | constructor(errors: Array<Throwable>) {
|
40 | let reasons = ""
|
41 | for (const e of errors.slice(0, 2)) {
|
42 | let message = ""
|
43 | if (e instanceof Error) {
|
44 | message = `${e.name}(${e.message})`
|
45 | } else {
|
46 | message = `${e}`
|
47 | }
|
48 | reasons += ", " + message
|
49 | }
|
50 |
|
51 | reasons = reasons.slice(2)
|
52 | if (errors.length > 2) reasons = reasons + ", ..."
|
53 | super(reasons)
|
54 |
|
55 | this.name = "CompositeError"
|
56 | this.errorsRef = errors
|
57 |
|
58 | // Workaround to make `instanceof` work in ES5
|
59 | const self = this as any
|
60 | self.constructor = CompositeError
|
61 | self.__proto__ = CompositeError.prototype
|
62 | }
|
63 |
|
64 | /**
|
65 | * Returns the full list of caught errors.
|
66 | */
|
67 | public errors(): Array<Throwable> { return this.errorsRef.slice() }
|
68 | }
|
69 |
|
70 | /**
|
71 | * A dummy error that can be used for testing purposes.
|
72 | */
|
73 | export class DummyError extends Error {
|
74 | constructor(message?: string) {
|
75 | super(message)
|
76 | this.name = "DummyError"
|
77 |
|
78 | // Workaround to make `instanceof` work in ES5
|
79 | const self = this as any
|
80 | self.constructor = DummyError
|
81 | self.__proto__ = DummyError.prototype
|
82 | }
|
83 | }
|
84 |
|
85 | /**
|
86 | * Thrown by various accessor methods or partial functions to indicate
|
87 | * that the element being requested does not exist.
|
88 | */
|
89 | export class NoSuchElementError extends Error {
|
90 | constructor(message?: string) {
|
91 | super(message)
|
92 | this.name = "NoSuchElementError"
|
93 |
|
94 | // Workaround to make `instanceof` work in ES5
|
95 | const self = this as any
|
96 | self.constructor = NoSuchElementError
|
97 | self.__proto__ = NoSuchElementError.prototype
|
98 | }
|
99 | }
|
100 |
|
101 | /**
|
102 | * Error throw in class constructors by implementations that
|
103 | * are sealed or final.
|
104 | */
|
105 | export class IllegalInheritanceError extends Error {
|
106 | constructor(message?: string) {
|
107 | super(message)
|
108 | this.name = "IllegalInheritanceError"
|
109 |
|
110 | // Workaround to make `instanceof` work in ES5
|
111 | const self = this as any
|
112 | self.constructor = IllegalInheritanceError
|
113 | self.__proto__ = IllegalInheritanceError.prototype
|
114 | }
|
115 | }
|
116 |
|
117 | /**
|
118 | * Signals that a function has been invoked at an illegal
|
119 | * or inappropriate time.
|
120 | *
|
121 | * In other words, environment or application is not in an
|
122 | * appropriate state for the requested operation.
|
123 | */
|
124 | export class IllegalStateError extends Error {
|
125 | constructor(message?: string) {
|
126 | super(message)
|
127 | this.name = "IllegalStateError"
|
128 |
|
129 | // Workaround to make `instanceof` work in ES5
|
130 | const self = this as any
|
131 | self.constructor = IllegalStateError
|
132 | self.__proto__ = IllegalStateError.prototype
|
133 | }
|
134 | }
|
135 |
|
136 | /**
|
137 | * Signals that a function has been invoked with illegal
|
138 | * arguments.
|
139 | */
|
140 | export class IllegalArgumentError extends Error {
|
141 | constructor(message?: string) {
|
142 | super(message)
|
143 | this.name = "IllegalArgumentError"
|
144 |
|
145 | // Workaround to make `instanceof` work in ES5
|
146 | const self = this as any
|
147 | self.constructor = IllegalArgumentError
|
148 | self.__proto__ = IllegalArgumentError.prototype
|
149 | }
|
150 | }
|
151 |
|
152 | /**
|
153 | * Signals that a function or a method is missing an implementation,
|
154 | * which should be provided in the future.
|
155 | */
|
156 | export class NotImplementedError extends Error {
|
157 | constructor(message?: string) {
|
158 | super(message)
|
159 | this.name = "NotImplementedError"
|
160 |
|
161 | // Workaround to make `instanceof` work in ES5
|
162 | const self = this as any
|
163 | self.constructor = NotImplementedError
|
164 | self.__proto__ = NotImplementedError.prototype
|
165 | }
|
166 | }
|
167 |
|
168 | /**
|
169 | * Signals that completion of a procedure took longer than anticipated.
|
170 | */
|
171 | export class TimeoutError extends Error {
|
172 | constructor(message?: string) {
|
173 | super(message)
|
174 | this.name = "TimeoutError"
|
175 |
|
176 | // Workaround to make `instanceof` work in ES5
|
177 | const self = this as any
|
178 | self.constructor = TimeoutError
|
179 | self.__proto__ = TimeoutError.prototype
|
180 | }
|
181 | }
|