VirtualBox

Changeset 38533 in vbox


Ignore:
Timestamp:
Aug 25, 2011 3:23:08 PM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
73681
Message:

Main/ErrorInfo: allow to set standard errors without text and error setting
from an existing com::ErrorInfo object

Location:
trunk/src/VBox/Main
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/include/VirtualBoxBase.h

    r37423 r38533  
    3535{
    3636class File;
     37}
     38
     39namespace com
     40{
     41class ErrorInfo;
    3742}
    3843
     
    746751                                    const GUID &aIID,
    747752                                    const char *aComponent,
    748                                     const Utf8Str &aText,
     753                                    Utf8Str aText,
    749754                                    bool aWarning,
    750755                                    bool aLogIt);
    751756    static void clearError(void);
    752757
     758    HRESULT setError(HRESULT aResultCode);
    753759    HRESULT setError(HRESULT aResultCode, const char *pcsz, ...);
     760    HRESULT setError(const ErrorInfo &ei);
    754761    HRESULT setWarning(HRESULT aResultCode, const char *pcsz, ...);
    755762    HRESULT setErrorNoLog(HRESULT aResultCode, const char *pcsz, ...);
  • trunk/src/VBox/Main/include/VirtualBoxErrorInfoImpl.h

    r30714 r38533  
    9494                 IVirtualBoxErrorInfo *aNext = NULL);
    9595
     96    HRESULT init(const com::ErrorInfo &ei,
     97                 IVirtualBoxErrorInfo *aNext = NULL);
     98
    9699    // IVirtualBoxErrorInfo properties
    97100    STDMETHOD(COMGETTER(ResultCode))(LONG *aResultCode);
  • trunk/src/VBox/Main/src-all/VirtualBoxBase.cpp

    r36451 r38533  
    306306                                         const GUID &aIID,
    307307                                         const char *pcszComponent,
    308                                          const Utf8Str &aText,
     308                                         Utf8Str aText,
    309309                                         bool aWarning,
    310310                                         bool aLogIt)
     
    328328                  (aWarning && aResultCode != S_OK),
    329329                  E_FAIL);
    330     AssertReturn(!aText.isEmpty(), E_FAIL);
    331330
    332331    /* reset the error severity bit if it's a warning */
     
    335334
    336335    HRESULT rc = S_OK;
     336
     337    if (aText.isEmpty())
     338    {
     339        /* Some default info */
     340        switch (aResultCode)
     341        {
     342            case E_INVALIDARG:                 aText = "A parameter has an invalid value"; break;
     343            case E_POINTER:                    aText = "A parameter is an invalid pointer"; break;
     344            case E_UNEXPECTED:                 aText = "The result of the operation is unexpected"; break;
     345            case E_ACCESSDENIED:               aText = "The access to an object is not allowed"; break;
     346            case E_OUTOFMEMORY:                aText = "The allocation of new memory failed"; break;
     347            case E_NOTIMPL:                    aText = "The requested operation is not implemented"; break;
     348            case E_NOINTERFACE:                aText = "The requested interface is not implemented"; break;
     349            case E_FAIL:                       aText = "A general error occurred"; break;
     350            case E_ABORT:                      aText = "The operation was canceled"; break;
     351            case VBOX_E_OBJECT_NOT_FOUND:      aText = "Object corresponding to the supplied arguments does not exist"; break;
     352            case VBOX_E_INVALID_VM_STATE:      aText = "Current virtual machine state prevents the operation"; break;
     353            case VBOX_E_VM_ERROR:              aText = "Virtual machine error occurred attempting the operation"; break;
     354            case VBOX_E_FILE_ERROR:            aText = "File not accessible or erroneous file contents"; break;
     355            case VBOX_E_IPRT_ERROR:            aText = "Runtime subsystem error"; break;
     356            case VBOX_E_PDM_ERROR:             aText = "Pluggable Device Manager error"; break;
     357            case VBOX_E_INVALID_OBJECT_STATE:  aText = "Current object state prohibits operation"; break;
     358            case VBOX_E_HOST_ERROR:            aText = "Host operating system related error"; break;
     359            case VBOX_E_NOT_SUPPORTED:         aText = "Requested operation is not supported"; break;
     360            case VBOX_E_XML_ERROR:             aText = "Invalid XML found"; break;
     361            case VBOX_E_INVALID_SESSION_STATE: aText = "Current session state prohibits operation"; break;
     362            case VBOX_E_OBJECT_IN_USE:         aText = "Object being in use prohibits operation"; break;
     363            default:                           aText = "Unknown error"; break;
     364        }
     365    }
    337366
    338367    do
     
    456485 * @return
    457486 */
     487HRESULT VirtualBoxBase::setError(HRESULT aResultCode)
     488{
     489    return setErrorInternal(aResultCode,
     490                            this->getClassIID(),
     491                            this->getComponentName(),
     492                            "",
     493                            false /* aWarning */,
     494                            true /* aLogIt */);
     495}
     496
     497/**
     498 * Shortcut instance method to calling the static setErrorInternal with the
     499 * class interface ID and component name inserted correctly. This uses the
     500 * virtual getClassIID() and getComponentName() methods which are automatically
     501 * defined by the VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT macro.
     502 * @param aResultCode
     503 * @return
     504 */
    458505HRESULT VirtualBoxBase::setError(HRESULT aResultCode, const char *pcsz, ...)
    459506{
     
    471518
    472519/**
     520 * Shortcut instance method to calling the static setErrorInternal with the
     521 * class interface ID and component name inserted correctly. This uses the
     522 * virtual getClassIID() and getComponentName() methods which are automatically
     523 * defined by the VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT macro.
     524 * @param ei
     525 * @return
     526 */
     527HRESULT VirtualBoxBase::setError(const com::ErrorInfo &ei)
     528{
     529    /* whether multi-error mode is turned on */
     530    bool preserve = MultiResult::isMultiEnabled();
     531
     532    HRESULT rc = S_OK;
     533
     534    do
     535    {
     536        ComObjPtr<VirtualBoxErrorInfo> info;
     537        rc = info.createObject();
     538        if (FAILED(rc)) break;
     539
     540#if !defined (VBOX_WITH_XPCOM)
     541
     542        ComPtr<IVirtualBoxErrorInfo> curInfo;
     543        if (preserve)
     544        {
     545            /* get the current error info if any */
     546            ComPtr<IErrorInfo> err;
     547            rc = ::GetErrorInfo (0, err.asOutParam());
     548            if (FAILED(rc)) break;
     549            rc = err.queryInterfaceTo(curInfo.asOutParam());
     550            if (FAILED(rc))
     551            {
     552                /* create a IVirtualBoxErrorInfo wrapper for the native
     553                 * IErrorInfo object */
     554                ComObjPtr<VirtualBoxErrorInfo> wrapper;
     555                rc = wrapper.createObject();
     556                if (SUCCEEDED(rc))
     557                {
     558                    rc = wrapper->init (err);
     559                    if (SUCCEEDED(rc))
     560                        curInfo = wrapper;
     561                }
     562            }
     563        }
     564        /* On failure, curInfo will stay null */
     565        Assert(SUCCEEDED(rc) || curInfo.isNull());
     566
     567        /* set the current error info and preserve the previous one if any */
     568        rc = info->init(ei, curInfo);
     569        if (FAILED(rc)) break;
     570
     571        ComPtr<IErrorInfo> err;
     572        rc = info.queryInterfaceTo(err.asOutParam());
     573        if (SUCCEEDED(rc))
     574            rc = ::SetErrorInfo (0, err);
     575
     576#else // !defined (VBOX_WITH_XPCOM)
     577
     578        nsCOMPtr <nsIExceptionService> es;
     579        es = do_GetService (NS_EXCEPTIONSERVICE_CONTRACTID, &rc);
     580        if (NS_SUCCEEDED(rc))
     581        {
     582            nsCOMPtr <nsIExceptionManager> em;
     583            rc = es->GetCurrentExceptionManager (getter_AddRefs (em));
     584            if (FAILED(rc)) break;
     585
     586            ComPtr<IVirtualBoxErrorInfo> curInfo;
     587            if (preserve)
     588            {
     589                /* get the current error info if any */
     590                ComPtr<nsIException> ex;
     591                rc = em->GetCurrentException (ex.asOutParam());
     592                if (FAILED(rc)) break;
     593                rc = ex.queryInterfaceTo(curInfo.asOutParam());
     594                if (FAILED(rc))
     595                {
     596                    /* create a IVirtualBoxErrorInfo wrapper for the native
     597                     * nsIException object */
     598                    ComObjPtr<VirtualBoxErrorInfo> wrapper;
     599                    rc = wrapper.createObject();
     600                    if (SUCCEEDED(rc))
     601                    {
     602                        rc = wrapper->init (ex);
     603                        if (SUCCEEDED(rc))
     604                            curInfo = wrapper;
     605                    }
     606                }
     607            }
     608            /* On failure, curInfo will stay null */
     609            Assert(SUCCEEDED(rc) || curInfo.isNull());
     610
     611            /* set the current error info and preserve the previous one if any */
     612            rc = info->init(ei, curInfo);
     613            if (FAILED(rc)) break;
     614
     615            ComPtr<nsIException> ex;
     616            rc = info.queryInterfaceTo(ex.asOutParam());
     617            if (SUCCEEDED(rc))
     618                rc = em->SetCurrentException (ex);
     619        }
     620        else if (rc == NS_ERROR_UNEXPECTED)
     621        {
     622            /*
     623             *  It is possible that setError() is being called by the object
     624             *  after the XPCOM shutdown sequence has been initiated
     625             *  (for example, when XPCOM releases all instances it internally
     626             *  references, which can cause object's FinalConstruct() and then
     627             *  uninit()). In this case, do_GetService() above will return
     628             *  NS_ERROR_UNEXPECTED and it doesn't actually make sense to
     629             *  set the exception (nobody will be able to read it).
     630             */
     631            LogWarningFunc(("Will not set an exception because nsIExceptionService is not available "
     632                            "(NS_ERROR_UNEXPECTED). XPCOM is being shutdown?\n"));
     633            rc = NS_OK;
     634        }
     635
     636#endif // !defined (VBOX_WITH_XPCOM)
     637    }
     638    while (0);
     639
     640    AssertComRC (rc);
     641
     642    return SUCCEEDED(rc) ? ei.getResultCode() : rc;
     643}
     644
     645/**
    473646 * Like setError(), but sets the "warning" bit in the call to setErrorInternal().
    474647 * @param aResultCode
  • trunk/src/VBox/Main/src-all/VirtualBoxErrorInfoImpl.cpp

    r35368 r38533  
    1919#include "Logging.h"
    2020
     21#include <VBox/com/ErrorInfo.h>
     22
    2123// public initializer/uninitializer for internal purposes only
    2224////////////////////////////////////////////////////////////////////////////////
     
    3335    m_strText = strText;
    3436    mNext = aNext;
     37
     38    return S_OK;
     39}
     40
     41HRESULT VirtualBoxErrorInfo::init(const com::ErrorInfo &info,
     42                                  IVirtualBoxErrorInfo *aNext)
     43{
     44    m_resultCode = info.getResultCode();
     45    m_IID = info.getInterfaceID();
     46    m_strComponent = info.getComponent();
     47    m_strText = info.getText();
     48
     49    /* Recursively create VirtualBoxErrorInfo instances for the next objects. */
     50    const com::ErrorInfo *pInfo = info.getNext();
     51    if (pInfo)
     52    {
     53        ComObjPtr<VirtualBoxErrorInfo> nextEI;
     54        HRESULT rc = nextEI.createObject();
     55        if (FAILED(rc)) return rc;
     56        rc = nextEI->init(*pInfo, aNext);
     57        if (FAILED(rc)) return rc;
     58        mNext = nextEI;
     59    }else
     60        mNext = aNext;
    3561
    3662    return S_OK;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette