1use brink_format::{DecodeError, DefinitionId};
4
5#[derive(Debug, thiserror::Error)]
7pub enum RuntimeError {
8 #[error("bytecode decode error: {0}")]
9 Decode(#[from] DecodeError),
10
11 #[error("unresolved definition: {0}")]
12 UnresolvedDefinition(DefinitionId),
13
14 #[error("no root container found")]
15 NoRootContainer,
16
17 #[error("value stack underflow")]
18 StackUnderflow,
19
20 #[error("call stack underflow")]
21 CallStackUnderflow,
22
23 #[error("container stack underflow")]
24 ContainerStackUnderflow,
25
26 #[error("invalid choice index: {index} (available: {available})")]
27 InvalidChoiceIndex { index: usize, available: usize },
28
29 #[error("not waiting for choice")]
30 NotWaitingForChoice,
31
32 #[error("story has ended")]
33 StoryEnded,
34
35 #[error("unresolved global: {0}")]
36 UnresolvedGlobal(DefinitionId),
37
38 #[error("type error: {0}")]
39 TypeError(String),
40
41 #[error("division by zero")]
42 DivisionByZero,
43
44 #[error("unimplemented opcode: {0}")]
45 Unimplemented(String),
46
47 #[error("unresolved external function call: {0}")]
48 UnresolvedExternalCall(DefinitionId),
49
50 #[error("output capture underflow (no checkpoint)")]
51 CaptureUnderflow,
52
53 #[error("unknown flow: {0}")]
54 UnknownFlow(String),
55
56 #[error("flow already exists: {0}")]
57 FlowAlreadyExists(String),
58
59 #[error("ran out of content. Do you need a '-> DONE' or '-> END'?")]
60 RanOutOfContent,
61
62 #[error("step limit exceeded ({0} steps)")]
63 StepLimitExceeded(u64),
64
65 #[error("line limit exceeded ({0} lines in a single turn)")]
66 LineLimitExceeded(usize),
67
68 #[error("locale checksum mismatch: expected {expected:#010x}, got {actual:#010x}")]
69 LocaleChecksumMismatch { expected: u32, actual: u32 },
70
71 #[error("locale scope not in base program: {0}")]
72 LocaleScopeNotInBase(DefinitionId),
73
74 #[error("locale missing scope required by strict mode: {0}")]
75 LocaleScopeMissing(DefinitionId),
76
77 #[error(
78 "function evaluation yielded (a function called from the engine cannot present choices or end the story)"
79 )]
80 FunctionYielded,
81
82 #[error("no function evaluation in progress")]
83 NotEvaluatingFunction,
84
85 #[error("a function evaluation is already in progress on this flow")]
86 AlreadyEvaluatingFunction,
87
88 #[error("function not found: {0}")]
90 FunctionNotFound(String),
91
92 #[error("external '{0}' is async; cannot resolve during a synchronous call_function")]
96 AsyncExternalInCall(String),
97
98 #[error("no knot or stitch found at path '{0}'")]
101 UnknownPath(String),
102
103 #[error(
107 "cannot jump to '{path}': the flow is parked on unresolved external '{external}' — \
108 resolve it before jumping"
109 )]
110 JumpWhileAwaitingExternal { path: String, external: String },
111
112 #[error("'{target}' expects {expected} argument(s), got {got}")]
116 ArgCountMismatch {
117 target: String,
119 expected: u8,
121 got: usize,
123 },
124}