throwing exception from COM object's constructor 
Author Message
 throwing exception from COM object's constructor

Hello friends,

I have VB and C++ client apps using a C++ ATL/COM object that has some
initializing code in its in its constructor.  I want to be able to throw an
exception from the COM object's constructor if something goes wrong during
the initialization process.  If I call _com_raise_error(S_FALSE,
pErrorInfo), my VB client returns the string "Out of memory" when I call
Err.GetDescription().  This string "Out of memory" is different from the
string that I used to initialize the pErrorInfo object passed to
_com_raise_error.  How can I get my custom error messages across to the VB
(or C++) client when throwing an exception from the constructor of a COM
object?

I realize that I could create an Init method on the COM object and have all
the initializing done in there, and call return Error(...) if an exception
needs to be thrown to the higher scope.  But I am wondering if there is a
slick way to accomplish the same from the constructor without creating a new
method.

Thanks much,
Arvind.



Sat, 08 Jan 2005 00:38:15 GMT  
 throwing exception from COM object's constructor

Quote:

> I have VB and C++ client apps using a C++ ATL/COM object that has some
> initializing code in its in its constructor.  I want to be able to throw an
> exception from the COM object's constructor if something goes wrong during
> the initialization process.  If I call _com_raise_error(S_FALSE,
> pErrorInfo), my VB client returns the string "Out of memory" when I call
> Err.GetDescription().  This string "Out of memory" is different from the
> string that I used to initialize the pErrorInfo object passed to
> _com_raise_error.  How can I get my custom error messages across to the VB
> (or C++) client when throwing an exception from the constructor of a COM
> object?

> I realize that I could create an Init method on the COM object and have all
> the initializing done in there, and call return Error(...) if an exception
> needs to be thrown to the higher scope.  But I am wondering if there is a
> slick way to accomplish the same from the constructor without creating a new
> method.

Shouldn't this sort of thing go in FinalConstruct, which returns an
HRESULT to indicate success or failure?


Sat, 08 Jan 2005 02:52:09 GMT  
 throwing exception from COM object's constructor

Quote:
> Shouldn't this sort of thing go in FinalConstruct, which returns an
> HRESULT to indicate success or failure?

I looked up the FinalConstruct() method and found that it is only available
on the base classes CComAggObject, CComCachedTearOffObject, and
CComPolyObject.  The COM object I am working with is a regular COM
object....

Any other ideas?

Thanks much,
Arvind.



Sat, 08 Jan 2005 03:57:24 GMT  
 throwing exception from COM object's constructor

Quote:



> > Shouldn't this sort of thing go in FinalConstruct, which returns an
> > HRESULT to indicate success or failure?

> I looked up the FinalConstruct() method and found that it is only available
> on the base classes CComAggObject, CComCachedTearOffObject, and
> CComPolyObject.  The COM object I am working with is a regular COM
> object....

No, that's not the case, although the way the cross-referencing in the
documentation is set up does lead you to think that.  The root
implementation is located in CComObjectRootBase, which is the base
class of CComObjectRootEx.  The documentation for CComObjectRootEx does
include FinalConstruct, although it only discusses using it for
creating aggregates.


Sat, 08 Jan 2005 04:26:09 GMT  
 throwing exception from COM object's constructor

Quote:
> No, that's not the case, although the way the cross-referencing in the
> documentation is set up does lead you to think that.  The root
> implementation is located in CComObjectRootBase, which is the base
> class of CComObjectRootEx.  The documentation for CComObjectRootEx does
> include FinalConstruct, although it only discusses using it for
> creating aggregates.

Thanks - you're right.  I tried it, and the overridden FinalConstruct method
does indeed get called.  In that method, I only have one line of code:

HRESULT MyObj::FinalConstruct()
{
  return Error("my error msg");

Quote:
}

On the VB client, when I try to create MyObj, I get an error, and
Err.Description returns "Automation Error" and not "my error msg" as I was
expecting.

Also, I put a breakpoint in MyObj::MyObj() which has no source code in it,
and a breakpoint in the FinalConstruct method shown above.  I was expecting
each of these breakpoints to only be hit once each, but both these
breakpoints were hit 4 times each even though the VB client only has one
line of code that reads like:

set pObj = new MyObj

Any thoughts on what I may be doing wrong and how I can pass an
exception/error string to the VB client during the construction of a COM
object?

Thanks again for your time.
Cheers,
Arvind.



Sat, 08 Jan 2005 04:48:04 GMT  
 throwing exception from COM object's constructor

Quote:


> > No, that's not the case, although the way the cross-referencing in the
> > documentation is set up does lead you to think that.  The root
> > implementation is located in CComObjectRootBase, which is the base
> > class of CComObjectRootEx.  The documentation for CComObjectRootEx does
> > include FinalConstruct, although it only discusses using it for
> > creating aggregates.

> Thanks - you're right.  I tried it, and the overridden FinalConstruct
method
> does indeed get called.  In that method, I only have one line of code:

> HRESULT MyObj::FinalConstruct()
> {
>   return Error("my error msg");
> }

> On the VB client, when I try to create MyObj, I get an error, and
> Err.Description returns "Automation Error" and not "my error msg" as I was
> expecting.

> Also, I put a breakpoint in MyObj::MyObj() which has no source code in it,
> and a breakpoint in the FinalConstruct method shown above.  I was
expecting
> each of these breakpoints to only be hit once each, but both these
> breakpoints were hit 4 times each even though the VB client only has one
> line of code that reads like:

> set pObj = new MyObj

> Any thoughts on what I may be doing wrong and how I can pass an
> exception/error string to the VB client during the construction of a COM
> object?

You're not doing anything wrong.  COM doesn't support this capability (of
returning rich error information from FinalConstruct/Ojbect creation.  It
does support errors...just not rich errors).  If you need to do this you
must either:

1.  Create a factory class first that creates your sub objects (presumably
with a method called "CreateNNN").  If a failure occurs during creation,
return your rich error information from the factory's method.  Make sure you
mark your sub objects as non-creatable.

2.  Create your object normally, but throw no errors.  Add a method called
"Initialize" (or whatever) and throw your rich error message from there.



Sat, 08 Jan 2005 05:00:35 GMT  
 
 [ 6 post ] 

 Relevant Pages 

1. throwing exception from COM object's constructor

2. Throwing Exceptions in Constructors

3. OK to throw exception from constructor?

4. Issues With Exception Thrown In Constructors

5. Throwing exception in constructor!

6. Throwing C++ exceptions from within constructors

7. CPen constructor throws exception 0xE06D7363

8. Constructors that throw Exceptions - How to handle.

9. Throwing com exceptions across process boundaries...

10. ATL COM DLL :: DllRegisterserver throw exception 0x80029c4a

11. throwing exception from COM and catching it in ASP

12. Throw exception from ATL COM for both VB and VC++ client

 

 
Powered by phpBB® Forum Software