Skip to content

Commit

Permalink
Add JSError.stack, add Error conformance (#48)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
MaxDesiatov authored Sep 15, 2020
1 parent 36f6bdb commit 3220b3c
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -441,4 +441,5 @@ try test("Error") {
try expectEqual(error.name, "Error")
try expectEqual(error.message, message)
try expectEqual(error.description, "Error: test error")
try expectEqual(error.stack?.isEmpty, false)
}
28 changes: 22 additions & 6 deletions Sources/JavaScriptKit/BasicObjects/JSError.swift
Original file line number Diff line number Diff line change
@@ -1,20 +1,36 @@
public final class JSError {
private let ref: JSObject
/** A wrapper around the [JavaScript Error
class](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error) that
exposes its properties in a type-safe way.
*/
public final class JSError: Error {
/// The underlying JavaScript `Error` object.
public let jsObject: JSObject

/// The constructor function used to create new `Error` objects.
private static let constructor = JSObject.global.Error.function!

/// Creates a new instance of the JavaScript `Error` class with a given message.
public init(message: String) {
ref = Self.constructor.new([message])
jsObject = Self.constructor.new([message])
}

/// The error message of the underlying `Error` object.
public var message: String {
ref.message.string!
jsObject.message.string!
}

/// The name (usually corresponds to the name of the underlying class) of a given error.
public var name: String {
ref.name.string!
jsObject.name.string!
}

/// The JavaScript call trace that led to the creation of this error object.
public var stack: String? {
jsObject.stack.string
}
}

extension JSError: CustomStringConvertible {
public var description: String { ref.description }
/// The textual representation of this error.
public var description: String { jsObject.description }
}

0 comments on commit 3220b3c

Please sign in to comment.