Repository navigation
feat(l10n): localize CSV import errors by type - #162
Merged
Merged
Conversation
The CSV file-load path (CsvService -> CsvFileSerializer -> CsvRowConverter)
raised free-text Result.Fail/new Error for every deserialize failure, so a
CSV import error rendered raw English regardless of culture. Worse, a bad
cell showed just "Row 2": the untyped "Row N" wrapper stringified its inner,
and the localizer's fallback recursion dropped the column/value detail.
Type the CSV import errors so both paths localize by type:
- AtRowError -- a new composing row decorator (mirrors AtStepError). The
CsvRowConverter column wrap reuses the slice-3 AtColumnError (byte-
identical), and unknown-action reuses 4b's ActionByIdNotFoundError. So the
value chain composes: AtRowError -> AtColumnError -> typed value error,
rendering under ru as "Строка 2: Столбец «gas»: Значение 5 больше
максимума 4 для «amount»" -- Russian end to end.
- Leaf errors for action-column / body-empty / header-mismatch / not-found.
- CsvService IO/access failures become Rule-B exception-envelopes: a typed
error carrying filePath with CausedBy(ex); the localized headline drops the
raw ex.Message, which survives in the log via the existing LogWarning.
English is behavior-preserving except three flagged changes: AtRowError
gains ": {inner}" (a display fix), the ActionByIdNotFoundError reuse rewords
unknown-action, and the two envelopes drop ": {ex.Message}". The
FlattenMessage gate asserts stay green (the full chain now lives in the
composed .Message). Under ru the CSV import surface reads Russian.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
Problem
The CSV file-load path (
CsvService→CsvFileSerializer→CsvRowConverter) raised free-textResult.Fail(string)/new Error(string)for every deserialize failure, so a CSV import error rendered raw English regardless of culture. Worse, a bad cell showed just "Row 2": the untypedRow Nwrapper stringified its inner, andReasonLocalizer's fallback recursion dropped the column/value detail.What changed
9 new typed errors + 2 reuses, so both the
Localizeand panel paths localize by type:AtRowError— a new composing row decorator (mirrorsAtStepError).CsvRowConverter's column wrap reuses the slice-3AtColumnError(byte-identical, already composesLocalize(inner)), and unknown-action reuses 4b'sActionByIdNotFoundError. So the value chain composesAtRowError → AtColumnError → typed value error, rendering underruasСтрока 2: Столбец «gas»: Значение 5 больше максимума 4 для «amount»— Russian end to end.CsvServiceIO/access failures → Rule-B exception-envelopes: a typed error carryingfilePath, raised with.CausedBy(ex); the localized headline drops the rawex.Message, which survives in the log via the existing_logger.LogWarning.Behavior-preserving for English except three flagged changes:
AtRowErrorgains: {inner}(the display fix), theActionByIdNotFoundErrorreuse rewords unknown-action, and the two exception-envelopes drop: {ex.Message}. TheCsvPropertyValidationTests.FlattenMessagegate asserts stay green (the full chain now lives in the composed.Message). Underruthe CSV import surface reads Russian.Scope: CSV path only. Clipboard producer errors are slice 5c.
Verification
dotnet build SemiStep.slnx— 0 warnings.dotnet test SemiStep/SemiStep.Tests/SemiStep.Tests.csproj— 1629 passed, 0 failed.CsvImportLocalizationTestsdeserializes a bad-value CSV through the realCsvFileSerializerand asserts the full Russian chain underru(both theLocalizeand the panelReportFailurepaths).ReasonLocalizerTestspins the ru render of all 9 new types + the enLocalize == .Messageinvariant; the coverage test forces a case for each.Per-task commits before collapse
🤖 Generated with Claude Code