Skip to content

Add custom exception handlers to generated COM wrappers #114828

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

dongle-the-gadget
Copy link

Fixes #109522

This is an initial iteration to add custom exception handlers to
generated COM wrappers, through a new ExceptionToUnmanagedMarshaller
property in GeneratedComWrappersAttribute

Fix dotnet#109522
Copy link

Note regarding the new-api-needs-documentation label:

This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change.

1 similar comment
Copy link

Note regarding the new-api-needs-documentation label:

This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change.

@dotnet-policy-service dotnet-policy-service bot added the community-contribution Indicates that the PR has been added by a community member label Apr 19, 2025
Copy link
Contributor

Tagging subscribers to this area: @dotnet/interop-contrib
See info in area-owners.md if you want to be subscribed.

@dongle-the-gadget
Copy link
Author

@dotnet-policy-service agree

@dongle-the-gadget dongle-the-gadget changed the title Add ExceptionToUnmanagedMarshaller to GeneratedComInterfaceAttribute Add custom exception handlers to generated COM wrappers Apr 19, 2025
Resolves an issue with previous implementation, highlighted by Jeremy.
The previous implementation is overcomplicated and hooks into the
default exception logic, which is not ideal. This commit copies the
existing custom exception marshalling logic from the VTable stub
generator.
Copy link
Member

@jkoritzinsky jkoritzinsky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a few nits, but looking much better!

dongle-the-gadget and others added 2 commits April 19, 2025 11:25
Co-authored-by: Jeremy Koritzinsky <jkoritzinsky@gmail.com>
Co-authored-by: Jeremy Koritzinsky <jkoritzinsky@gmail.com>
{
if (exceptionToUnmanagedMarshaller.Value is not INamedTypeSymbol)
{
return null;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We generally don't use null for logical flow. This would mean the return type should be updated. I don't think we should be failing in this case as it will silent and difficult to reason about. A diagnostic would be more appropriate.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was based on InteropAttributeDataExtensions.WithValuesFromNamedArguments, which returns null if an invalid StringMarshalling type is passed. I'm not sure how this is handled particularly by GeneratedComInterfaceAttributeData.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is another one of the cases where we use null as our "unable to parse" sentinel (and in the caller we check for null and emit a diagnostic and replace with a sentinel). Can you confirm?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, it looks like there's no regards to null-checking here. Even today if you pass in an invalid type for StringMarshallingCustomType, i.e.

[GeneratedComInterface(StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(string*))]
public partial interface Foo;

the generator fails with a generic error message from Roslyn:

Generator 'ComInterfaceGenerator' failed to generate source. It will not contribute to the output and compilation errors may occur as a result. Exception was of type 'NullReferenceException' with message 'Object reference not set to an instance of an object.'

Co-authored-by: Aaron Robinson <arobins@microsoft.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
3 participants