Fix-forward 4/4: result fidelity (address) + SearXNG 403 message#30
Fix-forward 4/4: result fidelity (address) + SearXNG 403 message#30ronaldmannak wants to merge 1 commit into
Conversation
Final batch of the fix-forward backlog (#26). - SearchResult.address: preserve scalar sub-fields, stringifying non-string scalars (bool/int/double) instead of dropping them. Upstream's map[string]interface{} keeps original types; this keeps the [String: String] shape while no longer losing data. - SearxngBackend: split 401/403 handling - a 403 most often means the instance has JSON output disabled, so the message now leads with that fix (add "json" to settings.yml formats) instead of only mentioning credentials. Tests updated/added accordingly. Deliberately NOT included (documented on the PR): - thumbnail / thumbnail_src: upstream's SearchResult has no such fields, so adding them would diverge from the "matches upstream --json" contract. - Cross-suite MockURLProtocol.handler isolation: robust fix needs a cross-suite serialization refactor, risky to land without a local toolchain; deferred (latent, unobserved - CI has been green). https://claude.ai/code/session_01NAsKiDMs1XHKYV22umnV5A
There was a problem hiding this comment.
Code Review
This pull request improves the decoding of the address field in SearchResult by preserving and stringifying scalar sub-fields (booleans, integers, and doubles) instead of skipping them. It also refactors the SearxngBackend error handling to provide a more helpful error message for HTTP 403 responses, suggesting that JSON output might be disabled. The feedback suggests using Int64 instead of Int during decoding to prevent potential failures on 32-bit platforms when handling large integers.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| } else if let value = try? nested.decode(Int.self, forKey: key) { | ||
| dict[key.stringValue] = String(value) |
There was a problem hiding this comment.
On 32-bit platforms (such as watchOS or older iOS devices), Int is represented as a 32-bit integer. If the address dictionary contains a 64-bit integer (e.g., a large ID, timestamp, or counter), decoding it using Int.self will fail on those platforms, causing it to fall back to Double (which can introduce precision loss or scientific notation formatting).
Using Int64.self instead of Int.self ensures robust decoding of large integers across all supported architectures.
| } else if let value = try? nested.decode(Int.self, forKey: key) { | |
| dict[key.stringValue] = String(value) | |
| } else if let value = try? nested.decode(Int64.self, forKey: key) { | |
| dict[key.stringValue] = String(value) |
Last of four stacked fix-forward PRs for #26. Stacked on #29; base is
claude/sx-fix-3-config-hardening.Fixes
SearchResult.addressdrops non-string sub-fields — upstream'sAddressismap[string]interface{}, but the port's decoder kept onlyStringvalues and silently dropped numbers/booleans. Now scalar sub-fields are preserved, stringifying non-string scalars (bool/int/double). This keeps the existing[String: String]shape (so the renderer is untouched) while no longer losing data."json"to theformatslist insettings.yml) instead of only mentioning credentials. Still.auth/ exit 7 (it's an instance-config problem).Tests
Updated the address-leniency test to assert preservation (
{"count": 3}→"count": "3"); 403 test now asserts the message mentionsJSON.Deliberately NOT included (from the #26 "fidelity / test-infra" group)
thumbnail/thumbnail_src— upstream'sSearchResultschema has no such fields (our port already matches it field-for-field). Adding them would diverge from the documented "--jsonmatches upstream" contract, so per the copy-upstream principle this is dropped rather than implemented.MockURLProtocol.handlerisolation — the suites are each@Suite(.serialized), but.serializeddoesn't serialize across suites, so the global handler is a latent (currently unobserved — CI's been green) flake risk. The robust fix is a cross-suite serialization refactor (nest all mock-using suites under one serialized parent, or route every test through a locked helper) — invasive and risky to land without a local Swift toolchain to iterate. Deferred; happy to do it as a follow-up with a compiler in the loop.No Swift toolchain locally → relies on CI for compile/test validation.
Generated by Claude Code