Fix DefaultTypeConverter.Convert bypassing subclass TryConvert overrides#2498
Merged
Conversation
Convert called the private TryConvert overload directly, which C# binds at compile time, so subclasses overriding the public virtual TryConvert were silently ignored on all Convert-driven interop paths (DelegateWrapper, MethodDescriptor, ReflectionAccessor, nested element conversions). Convert now dispatches through the public virtual TryConvert first and only falls back to the internal pipeline to produce the detailed error message and to honor exception propagation semantics (Options.Interop.ExceptionHandler). The private overload is renamed to TryConvertInternal so the silent overload binding cannot recur. Fixes sebastienros#2495 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
lahma
enabled auto-merge (squash)
June 7, 2026 06:59
This was referenced Jun 15, 2026
This was referenced Jun 24, 2026
This was referenced Jul 6, 2026
This was referenced Jul 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #2495
Problem
DefaultTypeConverter.Convertcalled the privateTryConvertoverload (the one withpropagateException/problemMessageparameters). C# binds that overload at compile time, so subclasses overriding the public virtualTryConvertwere silently bypassed on everyConvert-driven interop path:DelegateWrapper,MethodDescriptor,ReflectionAccessor,ObjectWrapper.Specialized, and nested element conversions inside the converter itself. OverridingTryConvertdid work for the probing callers (MethodInfoFunction,ObjectWrapper,IndexerAccessor), making the trap especially confusing — the override appeared half-working.Fix
Convertnow dispatches through the public virtualTryConvertfirst, so subclass overrides are honored. Only when that returnsfalsedoes it fall back to the internal pipeline to produce the detailed error message ("No valid constructors found for type …",FormatExceptiontext, etc.) and to honor exception propagation semantics (Options.Interop.ExceptionHandler— raw CLR exception still propagates to the host by default, JS error with the original message underCatchClrExceptions()).The private overload is renamed to
TryConvertInternalso the silent overload binding cannot recur, and both methods now have XML docs describing the dispatch contract (overrideTryConvert, callbase.TryConvertas fallback — neverConvert, which would recurse).No public API changes; behavior for the non-subclassed converter is unchanged on success paths, and failure paths produce identical messages/exceptions (the pipeline just runs once more to surface them).
Tests
New
DefaultTypeConverterTestscovering the issue repro (Action<Point>invoked with a plain JS object through an override-only converter), nested element conversions (Point[],List<Point>), directConvertcalls, detailed-error fidelity underCatchClrExceptions(), and raw exception propagation under default options.🤖 Generated with Claude Code