From f4b1446ece44eb06354086ea0da260ae8253c8c7 Mon Sep 17 00:00:00 2001 From: "mrbkap%gmail.com" Date: Mon, 3 Apr 2006 18:10:38 +0000 Subject: [PATCH] Don't ignore any errors returned by PostCreate. Also, don't override an exception if one is already reported, as the further away from the original problem we get, the less precise the error message will be. bug 326497, r=brendan sr=shaver --- js/src/xpconnect/src/xpcprivate.h | 1 + js/src/xpconnect/src/xpcthrower.cpp | 53 +++++++++++++++-------- js/src/xpconnect/src/xpcwrappednative.cpp | 6 ++- 3 files changed, 40 insertions(+), 20 deletions(-) diff --git a/js/src/xpconnect/src/xpcprivate.h b/js/src/xpconnect/src/xpcprivate.h index dbfdbdc70fa..54fc9c33c73 100644 --- a/js/src/xpconnect/src/xpcprivate.h +++ b/js/src/xpconnect/src/xpcprivate.h @@ -2515,6 +2515,7 @@ private: static void BuildAndThrowException(JSContext* cx, nsresult rv, const char* sz); static JSBool ThrowExceptionObject(JSContext* cx, nsIException* e); + static JSBool CheckForPendingException(nsresult result, XPCCallContext &ccx); private: static JSBool sVerbose; diff --git a/js/src/xpconnect/src/xpcthrower.cpp b/js/src/xpconnect/src/xpcthrower.cpp index a00da11b889..a33163dc154 100644 --- a/js/src/xpconnect/src/xpcthrower.cpp +++ b/js/src/xpconnect/src/xpcthrower.cpp @@ -49,11 +49,41 @@ void XPCThrower::Throw(nsresult rv, JSContext* cx) { const char* format; + if(JS_IsExceptionPending(cx)) + return; if(!nsXPCException::NameAndFormatForNSResult(rv, nsnull, &format)) format = ""; BuildAndThrowException(cx, rv, format); } +/* + * If there has already been an exception thrown, see if we're throwing the + * same sort of exception, and if we are, don't clobber the old one. ccx + * should be the current call context. + */ +// static +JSBool +XPCThrower::CheckForPendingException(nsresult result, XPCCallContext &ccx) +{ + nsXPConnect* xpc = nsXPConnect::GetXPConnect(); + if(!xpc) + return JS_FALSE; + + nsCOMPtr e; + xpc->GetPendingException(getter_AddRefs(e)); + if(!e) + return JS_FALSE; + xpc->SetPendingException(nsnull); + + nsresult e_result; + if(NS_FAILED(e->GetResult(&e_result)) || e_result != result) + return JS_FALSE; + + if(!ThrowExceptionObject(ccx, e)) + JS_ReportOutOfMemory(ccx); + return JS_TRUE; +} + // static void XPCThrower::Throw(nsresult rv, XPCCallContext& ccx) @@ -61,6 +91,9 @@ XPCThrower::Throw(nsresult rv, XPCCallContext& ccx) char* sz; const char* format; + if(CheckForPendingException(rv, ccx)) + return; + if(!nsXPCException::NameAndFormatForNSResult(rv, nsnull, &format)) format = ""; @@ -91,24 +124,8 @@ XPCThrower::ThrowBadResult(nsresult rv, nsresult result, XPCCallContext& ccx) * call. So we'll just throw that exception into our JS. */ - nsXPConnect* xpc = nsXPConnect::GetXPConnect(); - if(xpc) - { - nsCOMPtr e; - xpc->GetPendingException(getter_AddRefs(e)); - if(e) - { - xpc->SetPendingException(nsnull); - - nsresult e_result; - if(NS_SUCCEEDED(e->GetResult(&e_result)) && e_result == result) - { - if(!ThrowExceptionObject(ccx, e)) - JS_ReportOutOfMemory(ccx); - return; - } - } - } + if(CheckForPendingException(result, ccx)) + return; // else... diff --git a/js/src/xpconnect/src/xpcwrappednative.cpp b/js/src/xpconnect/src/xpcwrappednative.cpp index 9f4d2ae038e..4e61e0312d1 100644 --- a/js/src/xpconnect/src/xpcwrappednative.cpp +++ b/js/src/xpconnect/src/xpcwrappednative.cpp @@ -461,8 +461,10 @@ XPCWrappedNative::GetNewOrUsed(XPCCallContext& ccx, XPCNativeScriptableInfo* si = wrapper->GetScriptableInfo(); if(si && si->GetFlags().WantPostCreate()) { - si->GetCallback()-> - PostCreate(wrapper, ccx, wrapper->GetFlatJSObject()); + rv = si->GetCallback()-> + PostCreate(wrapper, ccx, wrapper->GetFlatJSObject()); + if(NS_FAILED(rv)) + return rv; } }