From 3efcc29edb90a9d626598f4e9cc249418832411f Mon Sep 17 00:00:00 2001 From: Tzvetan Mikov Date: Tue, 27 Aug 2024 12:40:41 -0700 Subject: [PATCH] JSError: look for stack data in the prototype chain Summary: Look for stack data in the entire prototype chain in order to accommodate usage like the one in the test. See https://github.com/facebook/hermes/issues/1496 Differential Revision: D61870728 --- lib/VM/JSError.cpp | 8 +++++++- test/hermes/error-in-proto.js | 27 +++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 test/hermes/error-in-proto.js diff --git a/lib/VM/JSError.cpp b/lib/VM/JSError.cpp index e951fed378b..0a4867d6a05 100644 --- a/lib/VM/JSError.cpp +++ b/lib/VM/JSError.cpp @@ -54,7 +54,11 @@ void JSErrorBuildMeta(const GCCell *cell, Metadata::Builder &mb) { CallResult> JSError::getErrorFromStackTarget( Runtime &runtime, Handle targetHandle) { - if (targetHandle) { + MutableHandle mutHnd = + runtime.makeMutableHandle(targetHandle.get()); + targetHandle = mutHnd; + + while (targetHandle) { NamedPropertyDescriptor desc; bool exists = JSObject::getOwnNamedDescriptor( targetHandle, @@ -68,6 +72,8 @@ CallResult> JSError::getErrorFromStackTarget( if (vmisa(*targetHandle)) { return Handle::vmcast(targetHandle); } + + mutHnd.set(targetHandle->getParent(runtime)); } return runtime.raiseTypeError( "Error.stack getter called with an invalid receiver"); diff --git a/test/hermes/error-in-proto.js b/test/hermes/error-in-proto.js new file mode 100644 index 00000000000..f53f0c70c6f --- /dev/null +++ b/test/hermes/error-in-proto.js @@ -0,0 +1,27 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +// RUN: %hermes %s | %FileCheck --match-full-lines %s +// RUN: %shermes -exec %s | %FileCheck --match-full-lines %s + +const MyError = function(message) { + this.message = message; +}; +MyError.prototype = new Error; +MyError.prototype.name = 'MyError'; + + +try { + throw new MyError('1234') +} catch (e) { + if (e instanceof Error) + print("Caught Error", e.stack); + else + print("Caught non-Error"); +} +// CHECK: Caught Error MyError: 1234 +// CHECK-NEXT: at global{{.*}}