Skip to content

Integration with the Visual Studio 'Exception Settings' Window

Andrew Crawley edited this page Feb 1, 2018 · 1 revision

Integration with the Visual Studio "Exception Settings" window

Visual Studio's "Exception Settings" window provides an improved exception handling experience that allows a debugger's behavior when an exception is thrown to be customized at the level of individual exception types. Debug adapters can benefit from this customizable experience by implementing the new "Exception Options" mechanism.

Visual Studio can be configured to enter break mode when an exception is received in one of three states:

  1. When the exception is thrown ("Break Always")
  2. When the exception is thrown and not handled by user code ("Break when User-Unhandled")
  3. When the exception is thrown and not handled by anyone ("Break when Unhandled")

Note that it is not possible to completely ignore an exception - Visual Studio will always enter break mode if an exception is unhandled.

To take advantage of this integration, debug adapters must:

  • Provide an exception category and set of exceptions registrations via the associated PKGDEF file.
  • Accept the ExceptionOptions objects passed in the exceptionOptions field of the setExceptionBreakpoints request.
  • Implement a handler for the exceptionInfo request.
  • Return true for the supportsExceptionOptions field in the Capabilities object returned in response to the initialize request.

Exception registration

Exceptions in Visual Studio belong to a category. This category and the set of exceptions it contains, along with their default state, are provided via the debug adapter's PKGDEF file. For an example of this registration, see the "Registration for the SampleDebugAdapter custom exceptions" section of the SampleDebugAdapter pkgdef.

The ExceptionOptions Object

Visual Studio passes a set of ExceptionInfo objects in the setExceptionBreakpoints request. Each ExceptionInfo provides a path, which consists of one or more ExceptionPathSegments that collectively represent some set of exceptions, and a breakMode that indicates under what circumstances the debug adapter should enter break mode when an exception matching that path is encountered. More specific rules (i.e. rules with a longer path) override more general ones. For example, consider this exceptionOptions value:

"exceptionOptions" : [
    { 
        "path": [ 
            { "names": ["Category1"] } 
        ],
        "breakMode": "userUnhandled" 
    },
    { 
        "path": [
            { "names": [ "Category1" ] }, 
            { "names": [ "ExceptionType1", "ExceptionType2" ]}
        ],
        "breakMode": "unhandled"
    },
    { 
        "path": [
            { "names": [ "Category1" ] },
            { "names": [ "ExceptionType3", "ExceptionType4" ] }
        ],
        "breakMode": "always"
    },
    { 
        "path": [ 
            { "names": [ "Category2" ] } 
        ],
        "breakMode": "always"
    },
    {
        "path": [
            { "names": [ "Category2" ] },
            { "names": [ "ExceptionTypeA", "ExceptionTypeB" ] } 
        ],
        "breakMode": "userUnhandled"
    }
]

This defines five ExceptionInfo objects, with the following meanings:

  1. All exceptions in "Category1" should break when unhandled by user code.
  2. Exceptions "ExceptionType1" and "ExceptionType2" in "Category1" should break when unhandled.
  3. Exceptions "ExceptionType3" and "ExceptionType4" in "Category1" should break when thrown.
  4. All exceptions in "Category2" should break when thrown.
  5. Exceptions "ExceptionTypeA" and "ExceptionTypeB" in "Category2" should break when unhandled by user code.

Examples:

  • Category1/ExceptionType1 - This exception type matches both rule 1 and rule 2, but rule 2 is more specific, so the debug adapter should only enter break mode if an exception of this type is unhandled.
  • Category2/ExceptionTypeC - This exception type matches rule 4 only, so the debug adapter should enter break mode when an exception of this type is thrown.

The exceptionInfo Request

When a debug adapter indicates that it has stopped due to an exception by raising a stopped event with the reason field set to exception, Visual Studio will attempt to obtain information about the exception by issuing an exceptionInfo request.

Visual Studio supports the following additional fields on the response to the exceptionInfo request:

Name Type Description
code integer Provides a numeric code associated with the exception, if any.

Visual Studio supports the following additional fields on any ExceptionDetails objects returned:

Name Type Description
formattedDescription string Provides a description that supports very basic formatting. Surround text with double asterisks (e.g. **text**) to display it in bold.
hresult integer Provides a Windows-style HRESULT associated with the exception, if any.
source string Provides the name of the object or application that raised the exception, if available.