Windows Dev Center

Exceptions (C++/CX)

Error handling in Visual C++ component extensions (C++/CX) is based on exceptions. At the most fundamental level, Windows Runtime components report errors as HRESULT values. In C++/CX, these values are converted to strongly typed exceptions. Exceptions are implemented as a ref class that derives from Platform::Exception. The Platform namespace defines distinct exception classes for the most common HRESULT values; all other values are reported through the Platform::COMException class. All exception classes have an HResult field that you can use to retrieve the original HRESULT.

In your C++ program, you can throw and catch an exception that comes from a Windows Runtime operation, an exception that's derived from std::exception, or a user-defined type. You have to throw a Windows Runtime exception only when it will cross the application binary interface (ABI) boundary, for example, when the code that catches your exception is written in JavaScript. When a non-Windows Runtime C++ exception reaches the ABI boundary, the exception is translated into a Platform::FailureException exception, which represents an E_FAIL HRESULT. For more information about the ABI, see Creating Windows Runtime Components in C++.

You can declare a Platform::Exception by using one of two constructors that take either an HRESULT parameter, or an HRESULT parameter and a Platform::String^ parameter that can be used for debug purposes. Or you can declare an exception by using one of two Platform::Exception::CreateException() method overloads that take either an HRESULT parameter, or an HRESULT parameter and a Platform::String^ parameter.

C++/CX supports a set of standard exceptions that represent typical HRESULT errors. Each standard exception derives from Platform::COMException, which in turn derives from Platform::Exception. When you throw an exception across the ABI boundary, you must throw one of the standard exceptions.

You can't derive your own exception type from Platform::Exception. To throw a custom exception, use a user-defined HRESULT to construct a COMException object.

The following table lists the standard exceptions.

Name

Underlying HRESULT

Description

COMException

user-defined hresult

Thrown when an unrecognized HRESULT is returned from a COM method call.

AccessDeniedException

E_ACCESSDENIED

Thrown when access is denied to a resource or feature.

ChangedStateException

E_CHANGED_STATE

Thrown when methods of a collection iterator or a collection view are called after the parent collection has changed, thereby invalidating the results of the method.

ClassNotRegisteredException

REGDB_E_CLASSNOTREG

Thrown when a COM class has not been registered.

DisconnectedException

RPC_E_DISCONNECTED

Thrown when an object is disconnected from its clients.

FailureException

E_FAIL

Thrown when an operation fails.

InvalidArgumentException

E_INVALIDARG

Thrown when one of the arguments that are provided to a method is not valid.

InvalidCastException

E_NOINTERFACE

Thrown when a type can't be cast to another type.

NotImplementedException

E_NOTIMPL

Thrown if an interface method hasn't been implemented on a class.

NullReferenceException

E_POINTER

Thrown when there is an attempt to de-reference a null object reference.

ObjectDisposedException

RO_E_CLOSED

Thrown when an operation is performed on a disposed object.

OperationCanceledException

E_ABORT

Thrown when an operation is aborted.

OutOfBoundsException

E_BOUNDS

Thrown when an operation attempts to access data outside the valid range.

OutOfMemoryException

E_OUTOFMEMORY

Thrown when there's insufficient memory to complete the operation.

WrongThreadException

RPC_E_WRONG_THREAD

Thrown when a thread calls via an interface pointer which is for a proxy object that does not belong to the thread's apartment.

All exceptions have an HResult property and a Message property. The HResult property gets the exception's underlying numeric HRESULT value. The Message property gets the system-supplied string that describes the exception. Because this property is read-only, you cannot change it when you rethrow the exception.

This example shows how to throw a Windows Runtime exception for synchronous operations:

The next example shows how to catch the exception.


void Class2::ProcessString(String^ input)
{
    String^ result = nullptr;    
    auto obj = ref new Class1();

    try 
    {
        result = obj->MyMethod(input);
    }

    catch (InvalidArgumentException^ e)
    {
        // Handle the exception in a way that's appropriate 
        // for your particular scenario. Assume
        // here that this string enables graceful
        // recover-and-continue. Why not?
        result = ref new String(L"forty two");

        // You can use Exception data for logging purposes.
        Windows::Globalization::Calendar calendar;
        LogMyErrors(calendar.GetDateTime(), e->HResult, e->Message);
    }

    // Execution continues here in both cases.
    //#include <string>
    std::wstring ws(result->Data());
    //...
}


To catch exceptions that are thrown during an asynchronous operation, use the task class with an error-handling continuation. The error-handling continuation marshals exceptions that are thrown on other threads back to the calling thread so that you can handle all potential exceptions at just one point in your code. For more information, see Asynchronous Programming in C++.

C++/CX does not use the finally clause.

Show:
© 2015 Microsoft