Repository navigation
Report all missing members in a response, not just the first - #458
Merged
Merged
Conversation
LogWarningOnErrorAndContinue and ThrowOnError now deserialize once with MissingMemberHandling.Error and a per-call error handler that records each missing member and marks it handled, so the rest of the response still binds. Members nested inside a missing member are recorded while Newtonsoft skips the value. Other errors still throw as before. Adds MerakiClientOptions.JsonMissingMembersAction, JsonMissingMember and JsonMissingMembersException. JsonMissingMemberAction is still called once with the first member's exception and is documented as superseded. LogWarningOnErrorAndContinue no longer deserializes affected responses twice. Closes #457
Up to standards ✅🟢 Issues
|
| Metric | Results |
|---|---|
| Complexity | 78 |
🟢 Coverage 85.29% diff coverage · +0.59% coverage variation
Metric Results Coverage variation ✅ +0.59% coverage variation Diff coverage ✅ 85.29% diff coverage Coverage variation details
Coverable lines Covered lines Coverage Common ancestor commit (942e697) 7964 3061 38.44% Head commit (ddfd69b) 8067 (+103) 3148 (+87) 39.02% (+0.59%) Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch:
<coverage of head commit> - <coverage of common ancestor commit>Diff coverage details
Coverable lines Covered lines Diff coverage Pull request (#458) 102 87 85.29% Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified:
<covered lines added or modified>/<coverable lines added or modified> * 100%
AI Reviewer: run a review on demand. To trigger the first review automatically, go to your organization or repository integration settings. AI can make mistakes. Always validate suggestions.
TIP This summary will be updated as you push new changes.
Split the lazy list assignment from the Add call, compare the benchmark modulus with zero, and use or suppress the ILogger parameters the test logger must declare.
danielabbatt
force-pushed
the
claude/report-all-missing-members-0ffe0f
branch
from
October 26, 2026 10:15
55d33a2 to
d9f844e
Compare
…sing-members-0ffe0f # Conflicts: # CHANGELOG.md
…sing-members-0ffe0f # Conflicts: # CHANGELOG.md
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.
Closes #457.
Summary
Under
JsonMissingMemberHandling.LogWarningOnErrorAndContinueandThrowOnError, the response is now deserialized once withMissingMemberHandling.Errorand a per-callJsonSerializer.Errorhandler. Each missing-member error is recorded and marked handled, so Newtonsoft skips that member's value and carries on binding the rest of the object and later array items. A smallJsonTextReadersubclass records the property names inside a skipped value, so members nested inside a missing member are reported too. Every other error is left unhandled and propagates exactly as before.MerakiClientOptions.JsonMissingMembersAction(Action<Type, IReadOnlyList<JsonMissingMember>, string>), called once per affected response with every missing member in document order.JsonMissingMember(DeclaringType,MemberName,Path). For a member nested in a missing member,DeclaringTypeis the modelled type that lacks the outermost one, andPathshows the nesting (unknownObject.deeper.leaf).JsonMissingMembersException : JsonSerializationExceptionwithMissingMembers, thrown byThrowOnError.JsonMissingMemberActionkept and documented as superseded.What counts as a missing member
A
JsonSerializationExceptionwhose message starts withCould not find member '. Newtonsoft raises exactly that (unlocalized) text, "Could not find member '{name}' on object of type '{type}'. Path '{path}', line 1, position 2.", whereverMissingMemberHandling.Errorrejects a member, and nowhere else. Anything else (JsonReaderException, "Error converting value", additional content, etc.) is not handled and throws as before.Behaviour, old vs new
IgnoreLogWarningOnErrorAndContinueoldLogWarningOnErrorAndContinuenewThrowOnErroroldThrowOnErrornewJsonMissingMemberActionJsonMissingMembersActionJsonMissingMemberResponseLogLevelJsonSerializationExceptionfor the first memberJsonMissingMembersException(aJsonSerializationException),InnerException= the old exception, samePath/line/position; message identical when there is one member, otherwise the first message plus the others' pathsOther errors:
JsonSerializationException, no missing member before itJsonMissingMemberActioncalled with it, rethrownJsonReaderException(invalid JSON, unparseable number)What existing consumers need to change
Nothing.
JsonMissingMemberActionis still called once per affected response with an exception whose message,Pathand type are the same as before. Code that catchesJsonSerializationExceptionfromThrowOnErrorstill catches the new exception. To get every member, setJsonMissingMembersAction.The one observable difference for
ThrowOnError: when a response has missing members and a later conversion error, the conversion error is now what is thrown (after the missing members are reported), where before the missing-member exception was.Is the partially built object correct?
Yes. Marking the error handled makes Newtonsoft skip only the offending member's value and continue with the next property, so every other member of that object, later array items and later top-level members still bind.
MissingMembersReportingTests.LogWarning_HandledMissingMembers_LeaveTheRestOfTheObjectBoundchecks a response with unknowns at the top level, on a nested object, as a nested object/array and on the middle array item, and asserts the result equals theIgnoreresult. A mutation run (not marking the error handled) fails 10 of the 19 tests.Tests
Meraki.Api.Test.Client.MissingMembersReportingTests, 19 tests, synthetic models and JSON:JsonMissingMembersActioncallIgnoreresult)ThrowOnError: both actions called, then oneJsonMissingMembersExceptionwith the full list; single-member message unchangedIgnoreunchangedOffline test run (
Meraki.Api.Test.exe -trait- Category=Integration): before 504 passed, after 523 passed (504 + 19 new), 0 failed.Benchmark
Benchmarks/MissingMemberDeserialization.cs, 200-item synthetic array, LogWarningOnErrorAndContinue,--job short:The no-missing-members path is within short-run noise (one extra closure and a bool check per token); the affected path is about 22% faster because the second pass is gone, while now reporting 12 members instead of 1.
Not changed
MerakiMcpResult.Deserializehas its ownThrowOnErrorhandling and still throws on the first missing member; it was out of scope here.