I beg to differ with @nobugz. E_NOINTERFACE
has the very specific meaning that your object does not support a certain interface that your client has just requested.
In general, you should only return E_NOINTERFACE
from your own IUnknown::QueryInterface()
. Returning E_NOINTERFACE
from DoStuff()
would surprise end users and tools alike. If I saw E_NOINTERFACE
coming from anywhere other than QueryInterface()
, my immediate thought would be "abstraction leak!".
At first sight, E_INVALIDARG
looks like the best options available -- after all, you were passed an argument that doesn't work for you. But in my view there is a subtlety here, so I'm not sure if I can make a universal rule out of that.
In an ideal world, the error codes returned by a COM method are more about the Interface than about the object. Concretely, IWellKnownInterface::DoStuff()
doesn't define (necessarily) that the object being passed in must implement ISpecificInterface
, or it would have a different argument type. So, technically you're cheating potential users of your object by not quite fully implementing the semantics of your interface. Of course, in the real world, it's very hard to create a meaningful open system if you make that into an absolute rule and interfaces are that rigid.
So: if you can provide reduced functionality that still meets the interface semantics even if your argument doesn't implement ISpecificInterface
, you should consider doing that.
Assuming that you must return in error: if this is a well-know, well documented (well designed?) interface, I would probably glance at the interface documentation first, to see if they give you any guidance. Lacking that, I would probably go ahead and use E_INVALIDARG
.
@Phil Booth has some nice recommendations about how to provide more information to your user about the nature of the error.
Obviously, if you had the chance you would want to change the interface to take a ISpecificInterface* param
instead.