v0.253.0 — errors carry the key of the sentence they are (R-557 slice 2 release B)
gates / gates (push) Successful in 24s
gates / gates (push) Successful in 24s
179 Hungarian sentences were built deep inside a package with fmt.Errorf and printed by whoever caught them: too late to translate where they are shown, too early where they are made. Every one now carries its key across that gap. ZERO Hungarian error literals remain. util.MsgError does three things at once, each earned: - Error() is the Hungarian, byte for byte, so every un-converted printer is unchanged; - errors.Is answers for the kind AND for a wrapped cause (KindErrorf dropped the cause); - an error ARGUMENT renders recursively, so "formázás sikertelen: %w" translates whole. A foreign error — restic, docker, ssh, the stdlib — prints verbatim. It is not ours. 76 display sites go through errText, and TestNoErrErrorInPageOutput convicts any that do not. memoryVerdict returns an error rather than a sentence, so the deploy's 409 and the household's language come from one value; UpdateRefusal gained a Cause to carry it. Plurals, one rule, stated once: a key with .one/.other takes its COUNT first. Not a per-call-site flag — the producer somebody forgot would read "3 app is not running". The guard caught a real key collision (alert.deadapp.one) the day the rule landed. TWO DEFECTS FOUND IN MY OWN TOOLING, recorded rather than quietly fixed. The bulk converter silently dropped multi-line concatenations, damaging 7 producers — and the parity gate could not see it, because every surviving fragment WAS a real base literal while the CALL had lost text; two behaviour tests caught it. And the counting script was case-sensitive, so it said "0 left" while five remained. MinAgent: 0.131.0 (unchanged). No hub release needed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
@@ -2,8 +2,8 @@ package backup
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"gitea.dooplex.hu/admin/felhom-controller/internal/util"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
@@ -25,26 +25,26 @@ import (
|
||||
|
||||
// Refusal reasons (customer-readable — they surface verbatim in the flash message).
|
||||
var (
|
||||
errNoTier2Copy = errors.New("nincs másodlagos fájlmásolat ehhez az alkalmazáshoz")
|
||||
errTier2DriveGone = errors.New("a másodlagos meghajtó nincs csatlakoztatva")
|
||||
errLiveDriveGone = errors.New("az alkalmazás meghajtója nincs csatlakoztatva")
|
||||
errLiveDriveDecommed = errors.New("az alkalmazás meghajtója le van szerelve")
|
||||
errNoTier2Copy = util.MsgError("err.backup.nincs_masodlagos_fajlmasolat_ehhez_az_alkalmazashoz")
|
||||
errTier2DriveGone = util.MsgError("err.backup.a_masodlagos_meghajto_nincs_csatlakoztatva")
|
||||
errLiveDriveGone = util.MsgError("err.backup.az_alkalmazas_meghajtoja_nincs_csatlakoztatva")
|
||||
errLiveDriveDecommed = util.MsgError("err.backup.az_alkalmazas_meghajtoja_le_van_szerelve")
|
||||
// errTier2OldLayout (3b, §7-G2): the recorded copy predates the v2 relpath-mirroring layout (no
|
||||
// marker). Refuse rather than read a flat layout we no longer understand — safe, because tier-2
|
||||
// restore is missing-file recovery and the live data still exists in that scenario.
|
||||
errTier2OldLayout = errors.New("A 2. mentés régi formátumú — futtass előbb egy új másodlagos mentést.")
|
||||
errTier2OldLayout = util.MsgError("err.backup.a_2_mentes_regi_formatumu_futtass")
|
||||
// ErrTier2NoRestorableData (C9-F1) — this app HAS a Tier-2 copy, but that copy contains no subtree
|
||||
// this restore can read: its data lives entirely in Docker named volumes, which are captured into
|
||||
// recovery-unit/ (db-dumps + volume-dumps) and NEVER read by this path. 43 of the 53 catalog apps
|
||||
// are in this class. Exported so the handler can refuse BEFORE stopping the app and name the action
|
||||
// that does work, instead of taking an outage and reporting "no missing files".
|
||||
ErrTier2NoRestorableData = errors.New("ennek az alkalmazásnak az adatai nem ebből a másolatból állíthatók vissza")
|
||||
ErrTier2NoRestorableData = util.MsgError("err.backup.ennek_az_alkalmazasnak_az_adatai_nem")
|
||||
// ErrTier2NoUnitInCopy (R-102) — the recorded Tier-2 copy holds no OPENABLE recovery unit: either
|
||||
// recovery-unit/ is absent, or it is a directory without a readable manifest.json. Exported so the
|
||||
// handler can refuse before beginning any op. FAIL CLOSED is the whole point of the second half:
|
||||
// a directory that exists is not a package, and reading a half-copied mirror as if it were one is
|
||||
// how a restore would overwrite live data with nothing.
|
||||
ErrTier2NoUnitInCopy = errors.New("a másodlagos másolatban nincs megnyitható mentési egység ehhez az alkalmazáshoz")
|
||||
ErrTier2NoUnitInCopy = util.MsgError("err.backup.a_masodlagos_masolatban_nincs_megnyithato_mentesi")
|
||||
)
|
||||
|
||||
// Tier2Coverage says what a Tier-2 restore can and cannot return for one app — the asymmetry C9-F1
|
||||
@@ -441,10 +441,10 @@ func (m *Manager) RestoreTier2Files(stackName string) (filesRestored int, err er
|
||||
}
|
||||
|
||||
if copyErr != nil {
|
||||
return filesRestored, fmt.Errorf("fájlmásolás sikertelen: %w", copyErr)
|
||||
return filesRestored, util.MsgError("err.backup.fajlmasolas_sikertelen", copyErr)
|
||||
}
|
||||
if startErr != nil {
|
||||
return filesRestored, fmt.Errorf("%d fájl visszaállítva, de az alkalmazás újraindítása sikertelen: %w", filesRestored, startErr)
|
||||
return filesRestored, util.MsgError("err.backup.fajl_visszaallitva_de_az_alkalmazas_ujrainditasa", filesRestored, startErr)
|
||||
}
|
||||
// Privacy: count + duration only — customer file names never at INFO.
|
||||
m.logger.Printf("[INFO] [backup] Tier-2 file restore completed for %s: %d file(s) restored (%s)",
|
||||
|
||||
Reference in New Issue
Block a user