返回 DeepSeek-Reasonix
transcript_initialization_error.go
根目录 / internal / session / transcript_initialization_error.go
1 package session
2
3 import (
4 "crypto/sha256"
5 "errors"
6 "fmt"
7 "log/slog"
8
9 "reasonix/internal/transcript"
10 )
11
12 // TranscriptInitializationError crosses service and migration boundaries
13 // without losing the original cause. LogValue never emits raw error text,
14 // session paths, provider metadata, or imported record identities.
15 type TranscriptInitializationError struct {
16 sessionID string
17 covered uint64
18 messageCount int
19 totalMessages int
20 cause error
21 }
22
23 func (e *TranscriptInitializationError) Error() string {
24 return fmt.Sprintf("session: initialize transcript for %q: %v", e.sessionID, e.cause)
25 }
26
27 func (e *TranscriptInitializationError) Unwrap() error { return e.cause }
28
29 // Classification returns a content-free reason suitable for aggregate crash
30 // diagnostics. Detailed correlation identifiers remain local-only in LogValue.
31 func (e *TranscriptInitializationError) Classification() string {
32 var baseline *transcript.BaselineError
33 if errors.As(e.cause, &baseline) {
34 return baseline.Code()
35 }
36 return "transcript_initialization_failed"
37 }
38
39 func (e *TranscriptInitializationError) LogValue() slog.Value {
40 attrs := []slog.Attr{
41 slog.Int("version", 1),
42 slog.String("code", "transcript_initialization_failed"),
43 slog.String("session_key", fmt.Sprintf("%x", sha256.Sum256([]byte(e.sessionID)))),
44 slog.Uint64("covered_sequence", e.covered),
45 slog.Int("baseline_message_count", e.messageCount),
46 slog.Int("baseline_total_message_count", e.totalMessages),
47 }
48 var baseline *transcript.BaselineError
49 if errors.As(e.cause, &baseline) {
50 attrs = append(attrs, slog.Any("baseline", baseline))
51 }
52 return slog.GroupValue(attrs...)
53 }
54
54 lines GO