ErrorInfo.h revision 094aa786a0135580c2b11a959f9e64062e35f560
/** @file
*
* MS COM / XPCOM Abstraction Layer:
* ErrorInfo class declaration
*/
/*
* Copyright (C) 2006-2007 innotek GmbH
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License as published by the Free Software Foundation,
* in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
* distribution. VirtualBox OSE is distributed in the hope that it will
* be useful, but WITHOUT ANY WARRANTY of any kind.
*
* If you received this file as part of a commercial VirtualBox
* distribution, then only the terms of your commercial VirtualBox
* license agreement apply instead of the previous paragraph.
*/
#ifndef __VBox_com_ErrorInfo_h__
#define __VBox_com_ErrorInfo_h__
struct IProgress;
struct IVirtualBoxErrorInfo;
{
/**
* The ErrorInfo class provides a convenient way to retrieve error
* information set by the most recent interface method, that was invoked on
* the current thread and returned an unsuccessful result code.
*
* Once the instance of this class is created, the error information for
* the current thread is cleared.
*
* There is no sence to use instances of this class after the last
* invoked interface method returns a success.
*
* The class usage pattern is as follows:
* <code>
* IFoo *foo;
* ...
* HRESULT rc = foo->SomeMethod();
* if (FAILED (rc)) {
* ErrorInfo info (foo);
* if (info.isFullAvailable()) {
* printf ("error message = %ls\n", info.getText().raw());
* }
* }
* </code>
*
* This class fetches error information using the IErrorInfo interface on
* Win32 (MS COM) or the nsIException interface on other platforms (XPCOM),
* or the extended IVirtualBoxErrorInfo interface when when it is available
* (i.e. a given IErrorInfo or nsIException instance implements it).
* Currently, IVirtualBoxErrorInfo is only available for VirtualBox components.
*
* ErrorInfo::isFullAvailable() and ErrorInfo::isBasicAvailable() determine
* what level of error information is available. If #isBasicAvailable()
* returns true, it means that only IErrorInfo or nsIException is available as
* the source of information (depending on the platform), but not
* IVirtualBoxErrorInfo. If #isFullAvailable() returns true, it means that all
* three interfaces are available. If both methods return false, no error info
* is available at all.
*
* Here is a table of correspondence between this class methods and
*
* ErrorInfo IErrorInfo nsIException IVirtualBoxErrorInfo
* --------------------------------------------------------------------
* getResultCode -- result resultCode
* getIID GetGUID -- interfaceID
* getComponent GetSource -- component
* getText GetDescription message text
*
* '--' means that this interface does not provide the corresponding portion
* of information, therefore it is useless to query it if only
* #isBasicAvailable() returns true. As it can be seen, the amount of
* information provided at the basic level, depends on the platform
* (MS COM or XPCOM).
*/
{
/**
* Constructs a new, "interfaceless" ErrorInfo instance that takes
* the error information possibly set on the current thread by an
* interface method of some COM component or by the COM subsystem.
*
* This constructor is useful, for example, after an unsuccessful attempt
* to instantiate (create) a component, so there is no any valid interface
* pointer available.
*/
: mIsBasicAvailable (false), mIsFullAvailable (false)
, mResultCode (S_OK)
{ init(); }
/**
* Constructs a new, "interfaceless" ErrorInfo instance that takes
* the error information possibly set on the current thread by an
* interface method of the given interface pointer.
* If the given interface does not support providing error information or,
* for some reason didn't set any error information, both
* #isFullAvailable() and #isBasicAvailable() will return |false|.
*
* @param aPtr pointer to the interface whose method returned an
* error
*/
: mIsBasicAvailable (false), mIsFullAvailable (false)
, mResultCode (S_OK)
/**
* Constructs a new ErrorInfo instance from the smart interface pointer.
* See template <class I> ErrorInfo (I *aPtr) for details
*
* @param aPtr smart pointer to the interface whose method returned
* an error
*/
: mIsBasicAvailable (false), mIsFullAvailable (false)
, mResultCode (S_OK)
/** Specialization for the IVirtualBoxErrorInfo smart pointer */
: mIsBasicAvailable (false), mIsFullAvailable (false)
, mResultCode (S_OK)
/**
* Constructs a new ErrorInfo instance from the IVirtualBoxErrorInfo
* interface pointer. If this pointer is not NULL, both #isFullAvailable()
* and #isBasicAvailable() will return |true|.
*
* @param aInfo pointer to the IVirtualBoxErrorInfo interface that
* holds error info to be fetched by this instance
*/
: mIsBasicAvailable (false), mIsFullAvailable (false)
, mResultCode (S_OK)
/**
* Returns whether basic error info is actually available for the current
* thread. If the instance was created from an interface pointer that
* supports basic error info and successfully provided it, or if it is an
* "interfaceless" instance and there is some error info for the current
* thread, the returned value will be true.
*
* See the class description for details about the basic error info level.
*
* The appropriate methods of this class provide meaningful info only when
* this method returns true (otherwise they simply return NULL-like values).
*/
bool isBasicAvailable() const { return mIsBasicAvailable; }
/**
* Returns whether full error info is actually available for the current
* thread. If the instance was created from an interface pointer that
* supports full error info and successfully provided it, or if it is an
* "interfaceless" instance and there is some error info for the current
* thread, the returned value will be true.
*
* See the class description for details about the full error info level.
*
* The appropriate methods of this class provide meaningful info only when
* this method returns true (otherwise they simply return NULL-like values).
*/
bool isFullAvailable() const { return mIsFullAvailable; }
/**
* Returns the COM result code of the failed operation.
*/
/**
* Returns the IID of the interface that defined the error.
*/
/**
* Returns the name of the component that generated the error.
*/
/**
* Returns the textual description of the error.
*/
/**
* Returns the next error information object or @c NULL if there is none.
*/
/**
* Returns the name of the interface that defined the error
*/
/**
* Returns the IID of the interface that returned the error.
*
* This method returns a non-null IID only if the instance was created
* using #template <class I> ErrorInfo (I *i) or
* template <class I> ErrorInfo (const ComPtr <I> &i) constructor.
*/
/**
* Returns the name of the interface that returned the error
*
* This method returns a non-null name only if the instance was created
* using #template <class I> ErrorInfo (I *i) or
* template <class I> ErrorInfo (const ComPtr <I> &i) constructor.
*/
/**
* Prints error information stored in this instance to the console.
* Intended mainly for debugging and for simple command-line tools.
*
* @param aPrefix optional prefix
*/
: mIsBasicAvailable (false), mIsFullAvailable (false)
, mResultCode (S_OK)
{}
bool mIsBasicAvailable : 1;
bool mIsFullAvailable : 1;
};
/**
* A convenience subclass of ErrorInfo that, given an IProgress interface
* pointer, reads its errorInfo attribute and uses the returned
* IVirtualBoxErrorInfo instance to construct itself.
*/
{
/**
* Constructs a new instance by fetchig error information from the
* IProgress interface pointer. If the progress object is not NULL,
* its completed attribute is true, resultCode represents a failure,
* and the errorInfo attribute returns a valid IVirtualBoxErrorInfo pointer,
* both #isFullAvailable() and #isBasicAvailable() will return true.
*
* @param progress the progress object representing a failed operation
*/
};
/**
* A convenience subclass of ErrorInfo that allows to preserve the current
* error info. Instances of this class fetch an error info object set on the
* current thread and keep a reference to it, which allows to restore it
* later using the #restore() method. This is useful to preserve error
* information returned by some method for the duration of making another COM
* call that may set its own error info and overwrite the existing
* one. Preserving and restoring error information makes sense when some
* method wants to return error information set by other call as its own
* error information while it still needs to make another call before return.
*
* Instead of calling #restore() explicitly you may let the object destructor
* do it for you, if you correctly limit the object's lifeime.
*
* The usage pattern is:
* <code>
* rc = foo->method();
* if (FAILED (rc))
* {
* ErrorInfoKeeper eik;
* ...
* // bar may return error info as well
* bar->method();
* ...
* // no need to call #restore() explicitly here because the eik's
* // destructor will restore error info fetched after the failed
* // call to foo before returning to the caller
* return rc;
* }
* </code>
*/
{
/** Constructs a new instance that will fetch the current error info. */
{ init (true /* aKeepObj */); }
/**
* Destroys this instance and automatically calls #restore() which will
* either restore error info fetched by the constructor or do nothing
* if #forget() was called before destruction. */
/**
* Restores error info fetched by the constructor and forgets it
* afterwards.
*
* @return COM result of the restore operation.
*/
/**
* Forgets error info fetched by the constructor to prevent it from
* being restored by #restore() or by the destructor.
*/
/**
* Forgets error info fetched by the constructor to prevent it from
* being restored by #restore() or by the destructor, and returns the
* stored error info object to the caller.
*/
bool mForgot : 1;
};
}; // namespace com
#endif // __VBox_com_ErrorInfo_h__