Skip to content

Unify Translation Error Contracts and Harden DOM Translation Lifecycles - #188

Open
Amm1rr wants to merge 198 commits into
mainfrom
refactor/error-path
Open

Unify Translation Error Contracts and Harden DOM Translation Lifecycles#188
Amm1rr wants to merge 198 commits into
mainfrom
refactor/error-path

Conversation

@Amm1rr

@Amm1rr Amm1rr commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator

Summary

This PR establishes a canonical translation-error contract across messaging, streaming, providers, and translation UIs, while hardening asynchronous DOM translation lifecycles across the extension.

Errors now preserve structured identity across transport boundaries and are presented through mode-owned, localized error policies instead of exposing raw provider diagnostics. The PR also strengthens stale-result protection, conversation acceptance, DOM ownership, restoration, editable-content safety, Shadow DOM support, and teardown behavior across Select Element, Whole Page, Field, PDF, and subtitle translation paths.

What Changed

Canonical Translation Error Contract

  • Added structured translation-error serialization and reconstruction across messaging and streaming boundaries.
  • Preserved canonical error identity through regular responses, streaming updates, terminal messages, iframe transport, lazy-loading failures, and translation coordinators.
  • Added safe public error presentation with localized messages, bounded provider details, severity, actions, and silent cancellation semantics.
  • Migrated translation surfaces to mode-owned error presentation, including Selection Windows, Fields, Whole Page, PDF, Subtitles, Mouse Hover, Mobile, and provider settings.
  • Preserved legacy error fields where compatibility is still required.

Select Element Reliability

  • Made conversation acceptance ACK delivery bounded, retryable, duplicate-safe, and cancellation-aware.
  • Strengthened parent identity and partial-result handling across conversation acceptance.
  • Hardened transactional DOM application and rollback so restoration failures do not prevent remaining recovery work.
  • Added Shadow DOM ancestry, direction, metadata, and rollback foundations while keeping Select Element Shadow translation behind its existing feature gate.

Whole Page Reliability

  • Added generation, session, source, and DOM-ownership guards before asynchronous results can mutate the page.
  • Prevented stale, detached, replaced, restored, or superseded work from applying late results.
  • Deferred successful settlement accounting until DOM application is actually accepted.
  • Protected mutable editable content and live form values while preserving translation of safe static attributes and visible BUTTON text.
  • Added open Shadow DOM traversal, persistent observation, dynamic-root discovery, movement handling, restoration, and cleanup.
  • Scoped restore, direction restoration, and translation-marker cleanup to the active translation root.

Field and Async Request Ownership

  • Added latest-request ownership for field translation, including supersession, stale-result suppression, timeout handling, pending-state ownership, and safe asynchronous insertion.
  • Consolidated Ctrl+/ handling through the shared shortcut infrastructure.
  • Hardened request tracking so stale element/toast cleanup cannot remove newer request ownership.

PDF, Subtitle, and Other Translation Paths

  • Propagated canonical error details through PDF and subtitle translation flows.
  • Preserved partial output while presenting terminal failures through the shared error policy.
  • Added stale-safe asynchronous error presentation for PDF and subtitle UI.
  • Aligned remaining translation surfaces with the canonical transport/presentation contract.

Lifecycle and Build Reliability

  • Added ownership and teardown cleanup for delayed DisplayManager activation.
  • Hardened asynchronous test lifecycle and timer ownership where required.
  • Added Chrome and Firefox production-bundle invariant validation.
  • Fixed lazy-loading boundaries that could produce production bundle TDZ failures.

Reliability Guarantees

  • Canonical error identity survives messaging and streaming reconstruction boundaries.
  • User-facing errors use safe localized presentation instead of raw provider responses.
  • Cancellation and invalid extension context remain silent where appropriate.
  • Late asynchronous results cannot overwrite user edits, replacement nodes, restored content, or newer translation work.
  • Whole Page translation does not mutate editable values or machine-valued form attributes.
  • Open Shadow DOM translation and restoration respect active session/root ownership.
  • Select Element conversation history no longer relies on fire-and-forget acceptance ACK delivery.
  • Delayed UI callbacks are cancelled during manager teardown.

Compatibility

  • Legacy error fields remain available alongside canonical errorDetails where required.
  • Existing consumers retain legacy fallback behavior during reconstruction.
  • Existing persisted Whole Page selector configuration is preserved; no selector migration is introduced.
  • Select Element Shadow DOM translation remains behind its existing disabled feature gate.
  • No dependency-version changes or locale migrations are included.

Documentation

Updated architecture and contract documentation for canonical error handling, messaging, provider behavior, Select Element lifecycle/rollback behavior, and production bundle validation.

Testing

  • Added and updated focused unit and integration coverage across messaging, streaming, Select Element, Whole Page, Shadow DOM, Field, PDF, Subtitles, providers, stale-result handling, rollback, and lifecycle cleanup.
  • 94 test files are changed in the branch.
  • Chrome and Firefox production-bundle invariant validation passed.
  • git diff --check passed.
  • Full Vitest and ESLint runs were completed.

Amm1rr added 30 commits August 16, 2026 22:46
Validate each Yandex translation item before returning the chunk so non-string or blank output for nonblank source text cannot be reported as successful.

Preserve blank source slots and valid identity translations, and avoid updating detected-language state when the response is invalid.
Validate Lingva delimiter-mapped results per source slot so blank or whitespace-only output for nonblank source text cannot be reported as a successful translation.

Preserve blank source positions, identity translations, cardinality handling, and atomic rebatched subgroup behavior.
Preserve raw scalar values when bridging top-level arrays into JSON_OBJECT format so null, numeric, and boolean translations remain visible to contract validation instead of being coerced into successful strings.

Keep quoted strings valid and preserve existing blank, identity, recovery, and missing-result violation semantics.
Harden ProviderCoordinator JSON-wrapped result handling by rejecting missing,
non-string, blank, and cardinality-invalid provider output instead of silently
substituting source text or returning partial results.

Preserve valid metadata reconstruction, identity translations, blank-source
compatibility, and rawJsonPayload behavior.
Stop using cached provider lastDetectedLanguage as request-local metadata or
language-detection feedback.

Use the current request's resolved source language instead, preventing stale
and concurrent provider state from contaminating AUTO resolution, detection
caches, and response metadata.
Reject non-string and unusable blank AI responses at the shared sequential STRING boundary before parser cleanup or coordinator coercion can turn them into successful translations.

Preserve valid quoted strings, identity translations, blank-source compatibility, and existing structured recovery behavior.
…ests

Thread request-local callPurpose through traditional provider batching and physical request execution without introducing shared provider state.

Preserve existing request-engine defaults, retry/failover behavior, and chunk-local ownership while correctly attributing non-primary recovery calls.
Enable OpenAI-style json_object response formatting for both JSON_OBJECT and JSON_ARRAY contracts in Custom and OpenRouter providers.

Keep STRING requests unconstrained and preserve existing request payload, parser, recovery, and endpoint behavior.
… slots

Introduce per-execution metadata slots owned by TranslationOperation so provider-produced metadata can be captured without storing request state on shared provider instances.

Keep retries and failover within the same semantic execution slot, publish successful executions at most once, and preserve separate primary/recovery records without changing existing translation result contracts.
Migrate provider-reported detected language from shared provider instance state into request-scoped provider execution metadata.

Capture validated detection for Google, Bing, Edge, DeepL, and Yandex, drop fabricated Vajehyab detection, and remove obsolete lastDetectedLanguage
state without changing public source-language or AUTO semantics.
Add deterministic operation-level aggregation for provider-reported metadata, normalize missing call purposes to primary translation, and publish metadata only after successful provider result validation and mapping.

Keep recovery metadata excluded from aggregation, preserve one metadata slot
across internal retries, and leave public detected-language and AUTO semantics
unchanged.
Document provider-reported detection as internal request-scoped metadata,
clarify that provider feedback is inactive, and add lifecycle coverage proving metadata publication stops after finalization while existing snapshots and aggregates remain readable and internal-only.
Remove unused BaseProvider sessionContext storage and stale session helper APIs
while preserving resetSessionContext as the compatibility cleanup hook used by provider-specific resource and token cleanup.

Add regression coverage for BrowserAPI resource disposal, Bing token reset, and ProviderFactory reset dispatch.
Reset request-scoped provider metadata for each internal execution attempt and discard metadata from failed attempts before retry.

Preserve one semantic execution slot across retries while ensuring only metadata produced by the successful attempt can be published and aggregated.
Document provider metadata as validated execution provenance and add regression coverage proving delivery failures do not invalidate successful provider
metadata.

Preserve partial-success metadata across later chunk failures while keeping stream delivery best-effort and independent from provider retry semantics.
Add an internal provider-detection diagnostic summary that distinguishes
absent, unanimous, and conflicting primary execution evidence.

Reuse the existing canonicalization rules while preserving semantic aggregation, recovery exclusion, finalization behavior, and all public translation contracts.
Retry structured Custom provider requests without response_format when an
endpoint explicitly rejects the parameter.

Keep the capability decision scoped to one semantic provider execution so internal retries avoid repeated probes while recovery, sequential items, and
new executions receive fresh capability state.

Refs: #164
Replace timing-based explicit-source concurrency synchronization with
deterministic provider-call observation, and convert the Yandex config mock to a partial mock that preserves required runtime exports.

Keep production AUTO and provider behavior unchanged while eliminating brittle test timing and stale config-mock failures.
- add canonical translation error serializer
- preserve provider error identity across generic translation paths
- delegate error response formatting to shared transport contract
- avoid arbitrary and duplicate error metadata serialization
- preserve explicit error type semantics
- serialize streaming failures with canonical error identity
- preserve provider error metadata across stream boundaries
- centralize translation error reconstruction
- retain stream-specific timestamp metadata
- keep timeout and lifecycle semantics unchanged
…ndaries

- reconstruct canonical errors in field translation failures
- preserve diagnostic identity after UI error handling
- unify selection window error reconstruction
- retain existing presentation and cancellation semantics
- transport canonical error details with page failures
- reconstruct provider error identity in scheduler
- keep page-specific error classification separate
- preserve legacy error fields and fatal semantics
- transport canonical error details across PDF failures
- preserve legacy PDF failure classification semantics
- reconstruct subtitle provider errors with canonical identity
- retain existing partial, fallback, and lifecycle behavior
- add canonical error details to legacy translation failures
- preserve existing string error contract
- sanitize transported provider error metadata
- keep extension API behavior unchanged
- serialize hover errors before cross-frame messaging
- add canonical sanitized error details
- preserve local native error behavior
- keep existing hover lifecycle semantics unchanged
- use canonical reconstruction for transported errors
- preserve Select Element fatal state explicitly
- prevent arbitrary transport metadata from reaching runtime errors
- retain translation outcome and cancellation semantics
- reconstruct resolved failures from canonical error identity
- remove arbitrary response metadata from thrown errors
- preserve legacy error message fallbacks
- keep restricted, runtime, timeout, and cancellation paths unchanged
- introduce immutable public translation error DTO
- add safe semantic mapping from canonical errors
- support bounded actionable metadata
- keep cancellation silent and raw diagnostics private
- limit HTTP status fallback to generic 400 invalid requests
- adapt public translation errors to legacy ErrorHandler contract
- map public semantic types to legacy error types
- localize display messages without exposing raw diagnostics
- preserve canonical error only as private cause
- keep runtime consumers unchanged
- route compatible terminal errors through public semantic policy
- adapt public errors to existing Select Element presentation
- retain legacy policy for behavior-sensitive error types
- preserve partial, cancellation, fatal, and cleanup semantics
Amm1rr added 30 commits August 23, 2026 18:02
- limit Google Classic and V2 rate-limit failures to 3 total executions
- keep provider retry policy request-local and provider-agnostic
- preserve generic retry budgets, health accounting, and Retry-After behavior
- limit traditional network providers to 3 total rate-limit executions
- preserve BrowserAPI and generic Queue retry defaults
- keep provider-internal retries, health, and circuit semantics unchanged
- classify SOCKS preflight timeout as network failure with precise provenance
- keep proxy timeout neutral to provider health without affecting generic network failures
- preserve user and internal cancellation provenance through SOCKS transport
- recognize both fb-* and fallback-* request IDs at fallback status boundaries
- preserve fb-* as the canonical fallback ID producer
- keep ordinary timeout probing and lifecycle semantics unchanged
- classify ambiguous AI HTTP 404 responses as HTTP_ERROR
- preserve provider-specific structured model-missing evidence
- keep retry, health, failover, and non-AI 404 semantics unchanged
- gate DeepL split recovery on shared request-size evidence
- avoid retrying generic and deterministic HTTP 400 failures
- preserve existing split, queue, health, quota, and failover semantics
- normalize Bing application-level 400 errors as HTTP_ERROR
- remove generic Bing 400 responses from adaptive chunking
- preserve existing HTML and JSON recovery semantics
- suppress retry actions for deterministic HTTP 400, 404, 413, and 422 failures
- derive translation retry affordances from the public error action
- propagate retry decisions through selection, PDF, page, and hover presentation paths
- preserve legacy error compatibility and existing execution retry semantics
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant