@@ -1523,7 +1523,38 @@ inline bool isBool() {
15231523 NSError * error = errorPtr[0 ];
15241524 std::free (errorRef);
15251525 if (error) {
1526- throw NativeScriptException ([[error localizedDescription ] UTF8String ]);
1526+ // Create JS Error with localizedDescription, attach code, domain and nativeException,
1527+ // and throw it into V8 so JS catch handlers receive it (with proper stack).
1528+ Isolate* isolate = methodCall.context_ ->GetIsolate ();
1529+ Local<Context> context = isolate->GetCurrentContext ();
1530+
1531+ Local<Value> jsErrVal = Exception::Error (tns::ToV8String (isolate, [[error localizedDescription ] UTF8String ]));
1532+ if (jsErrVal.IsEmpty () || !jsErrVal->IsObject ()) {
1533+ // Fallback: if for some reason we cannot create an Error object, throw a generic NativeScriptException
1534+ throw NativeScriptException ([[error localizedDescription ] UTF8String ]);
1535+ }
1536+
1537+ Local<Object> jsErrObj = jsErrVal.As <Object>();
1538+
1539+ // Attach the NSError code (number) and domain (string)
1540+ jsErrObj->Set (context, tns::ToV8String (isolate, " code" ), Number::New (isolate, (double )[error code ])).FromMaybe (false );
1541+ if (error.domain ) {
1542+ jsErrObj->Set (context, tns::ToV8String (isolate, " domain" ), tns::ToV8String (isolate, [error.domain UTF8String ])).FromMaybe (false );
1543+ } else {
1544+ jsErrObj->Set (context, tns::ToV8String (isolate, " domain" ), Null (isolate)).FromMaybe (false );
1545+ }
1546+
1547+ // Wrap the native NSError instance into a JS object and attach as nativeException
1548+ ObjCDataWrapper* wrapper = new ObjCDataWrapper (error);
1549+ Local<Value> nativeWrapper = ArgConverter::CreateJsWrapper (context, wrapper, Local<Object>(), true );
1550+ jsErrObj->Set (context, tns::ToV8String (isolate, " nativeException" ), nativeWrapper).FromMaybe (false );
1551+
1552+ // Ensure the Error has a proper 'name' property.
1553+ jsErrObj->Set (context, tns::ToV8String (isolate, " name" ), tns::ToV8String (isolate, " NSError" )).FromMaybe (false );
1554+
1555+ // Throw the JS Error with full stack information — V8 will populate the stack for the created Error object.
1556+ isolate->ThrowException (jsErrObj);
1557+ return Local<Value>();
15271558 }
15281559 }
15291560
0 commit comments