How to: Map HRESULTs and Exceptions

COM methods report errors by returning HRESULTs; .NET methods report them by throwing exceptions. The runtime handles the transition between the two. Each exception class in the .NET Framework maps to an HRESULT.

User-defined exception classes can specify whatever HRESULT is appropriate. These exception classes can dynamically change the HRESULT to be returned when the exception is generated by setting the HResult field on the exception object. Additional information about the exception is provided to the client through the IErrorInfo interface, which is implemented on the .NET object in the unmanaged process.

If you create a class that extends System.Exception, you must set the HRESULT field during construction. Otherwise, the base class assigns the HRESULT value. You can map new exception classes to an existing HRESULT by supplying the value in the exception's constructor.

Note that the runtime will sometimes ignore an HRESULT in cases where there is an IErrorInfo present on the thread. This behavior can occur in cases where the HRESULT and the IErrorInfo do not represent the same error.

To create a new exception class and map it to an HRESULT

  • Use the following code to create a new exception class called NoAccessException and map it to the HRESULT E_ACCESSDENIED.

    Class NoAccessException : public ApplicationException
    {
        NoAccessException () {
        HResult = E_ACCESSDENIED; 
    }
    }
    CMyClass::MethodThatThrows
    {
    throw new NoAccessException();
    }
    

You might encounter a program (in any programming language) that uses both managed and unmanaged code at the same time. For example, the custom marshaler in the following code example uses the Marshal.ThrowExceptionForHR(int HResult) method to throw an exception with a specific HRESULT value. The method looks up the HRESULT and generates the appropriate exception type. For example, the HRESULT in the following code fragment generates ArgumentException.

CMyClass::MethodThatThrows
{
    Marshal.ThrowExceptionForHR(COR_E_ARGUMENT);
}

The following table provides the complete mapping from each HRESULT to its comparable exception class in the .NET Framework.

HRESULT

.NET exception

MSEE_E_APPDOMAINUNLOADED

AppDomainUnloadedException

COR_E_APPLICATION

ApplicationException

COR_E_ARGUMENT or E_INVALIDARG

ArgumentException

COR_E_ARGUMENTOUTOFRANGE

ArgumentOutOfRangeException

COR_E_ARITHMETIC or ERROR_ARITHMETIC_OVERFLOW

ArithmeticException

COR_E_ARRAYTYPEMISMATCH

ArrayTypeMismatchException

COR_E_BADIMAGEFORMAT or ERROR_BAD_FORMAT

BadImageFormatException

COR_E_COMEMULATE_ERROR

COMEmulateException

COR_E_CONTEXTMARSHAL

ContextMarshalException

COR_E_CORE

CoreException

NTE_FAIL

CryptographicException

COR_E_DIRECTORYNOTFOUND or ERROR_PATH_NOT_FOUND

DirectoryNotFoundException

COR_E_DIVIDEBYZERO

DivideByZeroException

COR_E_DUPLICATEWAITOBJECT

DuplicateWaitObjectException

COR_E_ENDOFSTREAM

EndOfStreamException

COR_E_TYPELOAD

EntryPointNotFoundException

COR_E_EXCEPTION

Exception

COR_E_EXECUTIONENGINE

ExecutionEngineException

COR_E_FIELDACCESS

FieldAccessException

COR_E_FILENOTFOUND or ERROR_FILE_NOT_FOUND

FileNotFoundException

COR_E_FORMAT

FormatException

COR_E_INDEXOUTOFRANGE

IndexOutOfRangeException

COR_E_INVALIDCAST or E_NOINTERFACE

InvalidCastException

COR_E_INVALIDCOMOBJECT

InvalidComObjectException

COR_E_INVALIDFILTERCRITERIA

InvalidFilterCriteriaException

COR_E_INVALIDOLEVARIANTTYPE

InvalidOleVariantTypeException

COR_E_INVALIDOPERATION

InvalidOperationException

COR_E_IO

IOException

COR_E_MEMBERACCESS

AccessException

COR_E_METHODACCESS

MethodAccessException

COR_E_MISSINGFIELD

MissingFieldException

COR_E_MISSINGMANIFESTRESOURCE

MissingManifestResourceException

COR_E_MISSINGMEMBER

MissingMemberException

COR_E_MISSINGMETHOD

MissingMethodException

COR_E_MULTICASTNOTSUPPORTED

MulticastNotSupportedException

COR_E_NOTFINITENUMBER

NotFiniteNumberException

E_NOTIMPL

NotImplementedException

COR_E_NOTSUPPORTED

NotSupportedException

COR_E_NULLREFERENCE orE_POINTER

NullReferenceException

COR_E_OUTOFMEMORY or

E_OUTOFMEMORY

OutOfMemoryException

COR_E_OVERFLOW

OverflowException

COR_E_PATHTOOLONG or ERROR_FILENAME_EXCED_RANGE

PathTooLongException

COR_E_RANK

RankException

COR_E_REFLECTIONTYPELOAD

ReflectionTypeLoadException

COR_E_REMOTING

RemotingException

COR_E_SAFEARRAYTYPEMISMATCH

SafeArrayTypeMismatchException

COR_E_SECURITY

SecurityException

COR_E_SERIALIZATION

SerializationException

COR_E_STACKOVERFLOW orERROR_STACK_OVERFLOW

StackOverflowException

COR_E_SYNCHRONIZATIONLOCK

SynchronizationLockException

COR_E_SYSTEM

SystemException

COR_E_TARGET

TargetException

COR_E_TARGETINVOCATION

TargetInvocationException

COR_E_TARGETPARAMCOUNT

TargetParameterCountException

COR_E_THREADABORTED

ThreadAbortException

COR_E_THREADINTERRUPTED

ThreadInterruptedException

COR_E_THREADSTATE

ThreadStateException

COR_E_THREADSTOP

ThreadStopException

COR_E_TYPELOAD

TypeLoadException

COR_E_TYPEINITIALIZATION

TypeInitializationException

COR_E_VERIFICATION

VerificationException

COR_E_WEAKREFERENCE

WeakReferenceException

COR_E_VTABLECALLSNOTSUPPORTED

VTableCallsNotSupportedException

All other HRESULTs

COMException

To retrieve extended error information, the managed client must examine the fields of the exception object that was generated. For the exception object to provide useful information about an error, the COM object must implement the IErrorInfo interface. The runtime uses the information provided by IErrorInfo to initialize the exception object.

If the COM object does not support IErrorInfo, the runtime initializes an exception object with default values. The following table lists each field associated with an exception object and identifies the source of default information when the COM object supports IErrorInfo.

Note that the runtime will sometimes ignore an HRESULT in cases where there is an IErrorInfo present on the thread. This behavior can occur in cases where the HRESULT and the IErrorInfo do not represent the same error.

Exception field

Source of Information from COM

ErrorCode

HRESULT returned from call.

HelpLink

If IErrorInfo->HelpContext is nonzero, the string is formed by concatenating IErrorInfo->GetHelpFile and "#" and IErrorInfo->GetHelpContext. Otherwise the string is returned from IErrorInfo->GetHelpFile.

InnerException

Always a null reference (Nothing in Visual Basic).

Message

String returned from IErrorInfo->GetDescription.

Source

String returned from IErrorInfo->GetSource.

StackTrace

The stack trace.

TargetSite

The name of the method that returned the failing HRESULT.

Exception fields, such as Message, Source, and StackTrace are not available for the StackOverflowException.

See Also

Other Resources

Advanced COM Interoperability

Handling and Throwing Exceptions