Skip to content

[API Proposal]: Respect ISupportErrorInfo for HRESULT to Exception throwing conversion #117438

@AaronRobinsonMSFT

Description

@AaronRobinsonMSFT

Background and motivation

See #116917 for motivating example.

The Marshal.ThrowExceptionForHR() API respects IErrorInfo, but doesn't respect ISupportErrorInfo, which means implementing correct COM semantics isn't possible. The motivation here is for source generated COM. Built-in COM support respects ISupportErrorInfo as expected, but source generated COM can't since no public API exists that has the correct semantics.

API Proposal

A QI for ISupportErrorInfo will be performed on the pUnk. If ISupportErrorInfo is supported, the targetIID will then be passed to ISupportErrorInfo::InterfaceSupportsErrorInfo(). This will effectively allow users to then call GetExceptionForHR(int errorCode, IntPtr errorInfo) with the correct errorInfo value. If the interface doesn't support ISupportErrorInfo or the targetIID isn't supported, the errorInfo is thrown away. Throwing away the errorInfo isn't the expected COM behavior, but is the behavior observed by .NET Framework and built-in COM, therefore it will be followed here and documented. See #117438 (comment) for a proposed implementation. The PR for implementing this API should also replace the existing private API called by built-in COM interop.

namespace System.Runtime.InteropServices;

public static partial class Marshal
{
+    public static void ThrowExceptionForHR(int errorCode, Guid targetIID, IntPtr pUnk);
+    public static Exception? GetExceptionForHR(int errorCode, Guid targetIID, IntPtr pUnk);
}

API Usage

From within a source generated COM proxy:

Guid tgtIID = ...
Marshal.ThrowExceptionForHR(errorCode, tgtIID, pUnk);

Alternative Designs

No response

Risks

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    No status

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions