views:

23

answers:

2

I've written an ActiveX control in C++ that throws (C++) exceptions out when error conditions occur within the control. The Javascript code that invokes the object representing an instance of the control is surrounded by a try - catch block:

try
{
    var controlInstance = window.controlInstance;

    ... perform operations on controlInstance ...
}
catch (e)
{
    alert("something bad happened");
}

Now, when I run this code under IE8 (or 7 or 6) with a Visual Studio (2008) debugger attached to it, everything works as expected - whether the control is compiled with or without DEBUG on. However, when running the browser without a debugger attached, IE crashes (really) when an exception crosses the boundary between the control and JScript.

Does anyone have any suggestions around how to solve this problem? I realize that I can change the control's interface to pass the exception back as an argument but I really would rather not make such a change.

Any help would be appreciated.

+1  A: 

You can't pass C++ exceptions to the script - you need to catch the C++ exceptions in Invoke()/InvokeEx(), translate them and pass them out using the EXCEPINFO* parameter.

E.g. excerpting from FireBreaths implementation:

HRESULT YourIDispatchExImpl::InvokeEx(DISPID id, LCID lcid, WORD wFlags, 
                                      DISPPARAMS *pdp, VARIANT *pvarRes, 
                                      EXCEPINFO *pei, IServiceProvider *pspCaller)
{
    try {
        // do actual work
    } catch (const cppException& e) {
        if (pei != NULL) {
            pei->bstrSource = CComBSTR(ACTIVEX_PROGID);
            pei->bstrDescription = CComBSTR(e.what());
            // ...
        }
        return DISP_E_EXCEPTION;
    }

    // ...
Georg Fritzsche
A: 

You need AtlReportError. It throws javascript exception with description string:

STDMETHODIMP CMyCtrl::MyMethod()
{
   ...
   if (bSucceeded)
      return S_OK;
   else
      // hRes is set to DISP_E_EXCEPTION
      return AtlReportError (GetObjectCLSID(), "My error message");
}
Eugene