Skip to content

Commit 3220b3c

Browse files
authored
Add JSError.stack, add Error conformance (#48)
While the `stack` property is non-standard, it's [supported in all popular browser engines](https://caniuse.com/mdn-javascript_builtins_error_stack) and Node.js. Unfortunately, because `stack` value will be different on every machine that executes it, I'm not sure how to write a good test for it, so it currently has only a single test. Also, `JSError` now conforms to `Error`. The main reasoning is that the `Publisher` protocol in Combine requires `Error` conformance on its `Failure` type. I think in the future it would make sense to make `JSPromise` compatible with Combine, so it would be great if one could propagate errors produced by `JSPromise` to other publishers/subscribers.
1 parent 36f6bdb commit 3220b3c

File tree

2 files changed

+23
-6
lines changed

2 files changed

+23
-6
lines changed

IntegrationTests/TestSuites/Sources/PrimaryTests/main.swift

+1
Original file line numberDiff line numberDiff line change
@@ -441,4 +441,5 @@ try test("Error") {
441441
try expectEqual(error.name, "Error")
442442
try expectEqual(error.message, message)
443443
try expectEqual(error.description, "Error: test error")
444+
try expectEqual(error.stack?.isEmpty, false)
444445
}
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,36 @@
1-
public final class JSError {
2-
private let ref: JSObject
1+
/** A wrapper around the [JavaScript Error
2+
class](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error) that
3+
exposes its properties in a type-safe way.
4+
*/
5+
public final class JSError: Error {
6+
/// The underlying JavaScript `Error` object.
7+
public let jsObject: JSObject
8+
9+
/// The constructor function used to create new `Error` objects.
310
private static let constructor = JSObject.global.Error.function!
411

12+
/// Creates a new instance of the JavaScript `Error` class with a given message.
513
public init(message: String) {
6-
ref = Self.constructor.new([message])
14+
jsObject = Self.constructor.new([message])
715
}
816

17+
/// The error message of the underlying `Error` object.
918
public var message: String {
10-
ref.message.string!
19+
jsObject.message.string!
1120
}
1221

22+
/// The name (usually corresponds to the name of the underlying class) of a given error.
1323
public var name: String {
14-
ref.name.string!
24+
jsObject.name.string!
25+
}
26+
27+
/// The JavaScript call trace that led to the creation of this error object.
28+
public var stack: String? {
29+
jsObject.stack.string
1530
}
1631
}
1732

1833
extension JSError: CustomStringConvertible {
19-
public var description: String { ref.description }
34+
/// The textual representation of this error.
35+
public var description: String { jsObject.description }
2036
}

0 commit comments

Comments
 (0)