1package domain
2
3import "time"
4
5// NoticeSeverity ranks a user-facing notification.
6//
7// Its numeric values persist in JSON notice records and are a protocol/domain
8// contract. Add values only at the end; never reorder existing values.
9type NoticeSeverity uint8
10
11const (
12 NoticeInfo NoticeSeverity = iota
13 NoticeWarn
14 NoticeError
15)
16
17// NoticeCode identifies a failure meaning, not a call site.
18//
19// Its numeric values persist in JSON notice records and are a protocol/domain
20// contract. Add values only at the end; never reorder existing values.
21type NoticeCode uint16
22
23const (
24 NoticeInternal NoticeCode = iota
25 NoticePaneSpawn
26 NoticeTabSpawn
27 NoticeFloatingSpawn
28 NoticeSessionSpawn
29 NoticeLayoutTooSmall
30 NoticePaneNotFound
31 NoticeSessionUnavailable
32 NoticePersistDisabled
33 NoticeSnapshotWrite
34 NoticeSnapshotRestore
35 NoticeSnapshotSaturated
36 NoticePersistDelete
37 NoticeConfigReload
38 NoticeInputDropped
39 NoticeResizeFailed
40 NoticeClipboard
41 NoticeClipboardTooLarge
42 NoticeAutoResume
43 NoticeConnection
44 NoticeUser
45
46 // noticeCodeLimit is an append-only declaration sentinel, not a persisted
47 // valid notice code. Keep it last when adding a NoticeCode.
48 noticeCodeLimit
49)
50
51var noticeSlugs = map[NoticeCode]string{
52 NoticeInternal: "internal",
53 NoticePaneSpawn: "pane-spawn",
54 NoticeTabSpawn: "tab-spawn",
55 NoticeFloatingSpawn: "floating-spawn",
56 NoticeSessionSpawn: "session-spawn",
57 NoticeLayoutTooSmall: "layout-too-small",
58 NoticePaneNotFound: "pane-not-found",
59 NoticeSessionUnavailable: "session-unavailable",
60 NoticePersistDisabled: "persist-disabled",
61 NoticeSnapshotWrite: "snapshot-write",
62 NoticeSnapshotRestore: "snapshot-restore",
63 NoticeSnapshotSaturated: "snapshot-saturated",
64 NoticePersistDelete: "persist-delete",
65 NoticeConfigReload: "config-reload",
66 NoticeInputDropped: "input-dropped",
67 NoticeResizeFailed: "resize-failed",
68 NoticeClipboard: "clipboard",
69 NoticeClipboardTooLarge: "clipboard-too-large",
70 NoticeAutoResume: "auto-resume",
71 NoticeConnection: "connection",
72 NoticeUser: "user",
73}
74
75func (c NoticeCode) String() string {
76 if s, ok := noticeSlugs[c]; ok {
77 return s
78 }
79 return "unknown"
80}
81
82// UserError is an error whose message is written for the attached user.
83// The wrapped cause is shown only in yank details, never in the toast.
84type UserError struct {
85 Code NoticeCode
86 Severity NoticeSeverity
87 Msg string
88 Err error
89}
90
91func (e *UserError) Error() string {
92 if e.Err == nil {
93 return e.Msg
94 }
95 return e.Msg + ": " + e.Err.Error()
96}
97
98func (e *UserError) Unwrap() error { return e.Err }
99
100// UserErr wraps err as an error-severity user-facing failure.
101func UserErr(code NoticeCode, msg string, err error) *UserError {
102 return &UserError{Code: code, Severity: NoticeError, Msg: msg, Err: err}
103}
104
105// UserWarn wraps err as a warn-severity user-facing failure.
106func UserWarn(code NoticeCode, msg string, err error) *UserError {
107 return &UserError{Code: code, Severity: NoticeWarn, Msg: msg, Err: err}
108}
109
110// Notification is one entry in the daemon's user-facing notice history.
111type Notification struct {
112 Code NoticeCode
113 Severity NoticeSeverity
114 Message string
115 Details string // formatted error chain for yank
116 Time time.Time
117 Count int // >1 when coalesced
118 SessionID SessionID // "" = daemon-global
119}