From b66c0983b4943eebbfc09d911dfe02051f1637d4 Mon Sep 17 00:00:00 2001 From: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com> Date: Tue, 9 Jun 2026 07:54:37 +0000 Subject: [PATCH] fix(docs): continue partial i18n batches after file errors --- extensions/microsoft-foundry/onboard.ts | 2 +- scripts/docs-i18n/main.go | 8 ++-- scripts/docs-i18n/main_test.go | 54 +++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 5 deletions(-) diff --git a/extensions/microsoft-foundry/onboard.ts b/extensions/microsoft-foundry/onboard.ts index 8fa50ac64f30..2323116404e6 100644 --- a/extensions/microsoft-foundry/onboard.ts +++ b/extensions/microsoft-foundry/onboard.ts @@ -212,7 +212,7 @@ export async function selectFoundryDeployment( })), }); const selected = - supported.find((deployment) => deployment.name === selectedDeploymentName) ?? supported[0]!; + supported.find((deployment) => deployment.name === selectedDeploymentName) ?? supported[0]; return { selected, supported }; } diff --git a/scripts/docs-i18n/main.go b/scripts/docs-i18n/main.go index c3ca6299ab6b..087d763ac692 100644 --- a/scripts/docs-i18n/main.go +++ b/scripts/docs-i18n/main.go @@ -206,7 +206,7 @@ func runDocSequential(ctx context.Context, ordered []string, translator docsTran start := time.Now() skip, outputPath, err := processFileDoc(ctx, translator, docsRoot, file, srcLang, tgtLang, overwrite) if err != nil { - if shouldStopDocRun(ctx, allowPartial) { + if shouldStopDocRun(ctx, err, allowPartial) { return processed, skipped, outputs, err } if firstErr == nil { @@ -259,7 +259,7 @@ func runDocParallel(ctx context.Context, ordered []string, docsRoot, srcLang, tg skipped: skip, err: err, } - if err != nil && shouldStopDocRun(ctx, allowPartial) { + if err != nil && shouldStopDocRun(ctx, err, allowPartial) { cancel() return } @@ -306,11 +306,11 @@ func runDocParallel(ctx context.Context, ordered []string, docsRoot, srcLang, tg return processed, skipped, outputs, firstErr } -func shouldStopDocRun(ctx context.Context, allowPartial bool) bool { +func shouldStopDocRun(ctx context.Context, err error, allowPartial bool) bool { if !allowPartial { return true } - return ctx.Err() != nil + return ctx.Err() != nil || errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) } func runSegmentSequential(ctx context.Context, ordered []string, translator docsTranslator, tm *TranslationMemory, docsRoot, srcLang, tgtLang string) (int, []string, error) { diff --git a/scripts/docs-i18n/main_test.go b/scripts/docs-i18n/main_test.go index b775cc64ce4d..5d08d33ab7ed 100644 --- a/scripts/docs-i18n/main_test.go +++ b/scripts/docs-i18n/main_test.go @@ -126,6 +126,24 @@ func (cancelAwareTranslator) TranslateRaw(ctx context.Context, text, _, _ string func (cancelAwareTranslator) Close() {} +type contextErrorTranslator struct{} + +func (contextErrorTranslator) Translate(_ context.Context, text, _, _ string) (string, error) { + if strings.Contains(text, "CANCEL") { + return "", context.Canceled + } + return text, nil +} + +func (contextErrorTranslator) TranslateRaw(_ context.Context, text, _, _ string) (string, error) { + if strings.Contains(text, "CANCEL") { + return "", context.Canceled + } + return text, nil +} + +func (contextErrorTranslator) Close() {} + type cancelAfterFirstDocTranslator struct { cancel context.CancelFunc calls int @@ -376,6 +394,42 @@ func TestRunDocsI18NAllowPartialReturnsCancellationAfterPartialSuccess(t *testin } } +func TestRunDocsI18NAllowPartialStopsAfterContextError(t *testing.T) { + t.Parallel() + + docsRoot := t.TempDir() + writeFile(t, filepath.Join(docsRoot, ".i18n", "glossary.zh-CN.json"), "[]") + writeFile(t, filepath.Join(docsRoot, "docs.json"), `{"redirects":[]}`) + firstPath := filepath.Join(docsRoot, "aaa-first.md") + cancelPath := filepath.Join(docsRoot, "bbb-cancel.md") + laterPath := filepath.Join(docsRoot, "zzz-later.md") + writeFile(t, firstPath, "# Gateway\n") + writeFile(t, cancelPath, "# CANCEL\n") + writeFile(t, laterPath, "# Gateway\n") + + err := runDocsI18N(context.Background(), runConfig{ + targetLang: "zh-CN", + sourceLang: "en", + docsRoot: docsRoot, + mode: "doc", + thinking: "high", + overwrite: true, + allowPartial: true, + parallel: 1, + }, []string{firstPath, cancelPath, laterPath}, func(_, _ string, _ []GlossaryEntry, _ string) (docsTranslator, error) { + return contextErrorTranslator{}, nil + }) + if !errors.Is(err, context.Canceled) { + t.Fatalf("expected cancellation error to remain terminal, got %v", err) + } + if got := mustReadFile(t, filepath.Join(docsRoot, "zh-CN", "aaa-first.md")); !strings.Contains(got, "# Gateway") { + t.Fatalf("expected first output to be written before cancellation, got:\n%s", got) + } + if _, err := os.Stat(filepath.Join(docsRoot, "zh-CN", "zzz-later.md")); err == nil { + t.Fatal("did not expect later output to be written after context error") + } +} + func TestRunDocsI18NRewritesLineTitleFromExactGlossaryWithoutModel(t *testing.T) { t.Parallel()