1 // Copyright 2022-present 650 Industries. All rights reserved.
2 
3 public extension JavaScriptRuntime {
4   /**
5    Evaluates JavaScript code represented as a string.
6 
7    - Parameter source: A string representing a JavaScript expression, statement, or sequence of statements.
8                        The expression can include variables and properties of existing objects.
9    - Returns: The completion value of evaluating the given code represented as `JavaScriptValue`.
10               If the completion value is empty, `undefined` is returned.
11    - Throws: `JavaScriptEvalException` when evaluated code has invalid syntax or throws an error.
12    - Note: It wraps the original `evaluateScript` to better handle and rethrow exceptions.
13    */
14   @discardableResult
15   func eval(_ source: String) throws -> JavaScriptValue {
16     do {
17       var result: JavaScriptValue?
18       try EXUtilities.catchException {
19         result = self.evaluateScript(source)
20       }
21       // There is no risk to force unwrapping as long as the `evaluateScript` returns nonnull value.
22       return result!
23     } catch {
24       throw JavaScriptEvalException(error as NSError)
25     }
26   }
27 }
28 
29 internal final class JavaScriptEvalException: GenericException<NSError> {
30   override var reason: String {
31     return param.userInfo["message"] as? String ?? "unknown reason"
32   }
33 }
34