source2_demo/error.rs
1//! Error types for the parser.
2//!
3//! This module defines all error types that can occur during replay parsing.
4//! All errors implement the standard [`std::error::Error`] trait using
5//! [`thiserror`].
6//!
7//! # Error Types
8//!
9//! - [`ParserError`] - Main error type for parsing operations
10//! - [`EntityError`] - Errors related to entity operations
11//! - [`ClassError`] - Errors related to entity class lookups
12//! - [`StringTableError`] - Errors related to string table operations
13//! - [`GameEventError`] - Errors related to game event operations
14//! - [`FieldValueError`] - Errors related to field value conversions
15//!
16//! # Examples
17//!
18//! ## Handling errors
19//!
20//! ```no_run
21//! use source2_demo::prelude::*;
22//! use source2_demo::error::*;
23//!
24//! # fn example(ctx: &Context) {
25//! match ctx.entities().get_by_index(0) {
26//! Ok(entity) => println!("Entity: {}", entity.class().name()),
27//! Err(EntityError::IndexNotFound(idx)) => {
28//! println!("No entity at index {}", idx);
29//! }
30//! Err(e) => println!("Other error: {}", e),
31//! }
32//! # }
33//! ```
34
35/// Main error type for parser operations.
36///
37/// This error type covers all parsing-related errors including protobuf
38/// decoding, decompression, and various domain-specific errors.
39#[derive(thiserror::Error, Debug)]
40pub enum ParserError {
41 /// Protobuf decoding error
42 #[error(transparent)]
43 ProtobufDecode(#[from] crate::proto::prost::DecodeError),
44
45 /// Unknown enum value in protobuf
46 #[error(transparent)]
47 UnknownEnumValue(#[from] crate::proto::prost::UnknownEnumValue),
48
49 /// Snappy decompression error
50 #[error(transparent)]
51 SnapDecompress(#[from] snap::Error),
52
53 /// String table related error
54 #[error(transparent)]
55 StringTable(#[from] StringTableError),
56
57 /// Class lookup error
58 #[error(transparent)]
59 Class(#[from] ClassError),
60
61 /// Entity related error
62 #[error(transparent)]
63 Entity(#[from] EntityError),
64
65 /// Field value conversion error
66 #[error(transparent)]
67 FieldValue(#[from] FieldValueError),
68
69 /// Game event error
70 #[error(transparent)]
71 GameEvent(#[from] GameEventError),
72
73 /// Observer callback error
74 #[error(transparent)]
75 ObserverError(#[from] anyhow::Error),
76
77 /// Invalid CDemoFileInfo offset
78 #[error("Wrong CDemoFileInfo offset")]
79 ReplayEncodingError,
80
81 /// File is not a valid Source 2 demo
82 #[error("Supports only Source 2 replays")]
83 WrongMagic,
84
85 /// I/O error occurred during file operations
86 #[error("IO error: {0}")]
87 IoError(String),
88
89 #[cfg(feature = "dota")]
90 /// Combat log parsing error (Dota 2)
91 #[error(transparent)]
92 CombatLog(#[from] CombatLogError),
93
94 #[cfg(feature = "deadlock")]
95 /// Match details not found in Deadlock replay
96 #[error("CCitadelUserMsgPostMatchDetails not found")]
97 MatchDetailsNotFound,
98}
99
100/// Errors related to entity class operations.
101#[derive(thiserror::Error, Debug)]
102pub enum ClassError {
103 /// Class not found for the given ID
104 #[error("Class not found for the given id {0}")]
105 ClassNotFoundById(i32),
106
107 /// Class not found for the given name
108 #[error("Class not found for the given name {0}")]
109 ClassNotFoundByName(String),
110}
111
112/// Errors related to entity operations.
113#[derive(thiserror::Error, Debug)]
114pub enum EntityError {
115 /// No entity exists at the specified index
116 #[error("No entities found at index {0}")]
117 IndexNotFound(usize),
118
119 /// No entity exists with the specified handle
120 #[error("No entities found for handle {0}")]
121 HandleNotFound(usize),
122
123 /// No entity exists with the specified class ID
124 #[error("No entities found for class with id {0}")]
125 ClassIdNotFound(i32),
126
127 /// No entity exists with the specified class name
128 #[error("No entities found for class with name {0}")]
129 ClassNameNotFound(String),
130
131 /// Property not found on the entity
132 #[error("No property found for name {0} (Class: {1}, FieldPath: {2})")]
133 PropertyNameNotFound(String, String, String),
134
135 /// Field path not found in serializer
136 #[error(transparent)]
137 FieldPathNotFound(#[from] SerializerError),
138}
139
140/// Errors related to field value conversions.
141#[derive(thiserror::Error, Debug)]
142pub enum FieldValueError {
143 /// Failed to convert field value to target type
144 #[error("Cannot convert {0} into {1}")]
145 ConversionError(String, String),
146}
147
148/// Errors related to game event operations.
149#[derive(thiserror::Error, Debug)]
150pub enum GameEventError {
151 /// Unknown key in game event
152 #[error("Unknown key: {0}")]
153 UnknownKey(String),
154 /// Failed to convert event value to target type
155 #[error("Conversion error: {0} -> {1}")]
156 ConversionError(String, String),
157}
158
159/// Errors related to serializer operations.
160#[derive(thiserror::Error, Debug)]
161pub enum SerializerError {
162 /// No field path found for property name
163 #[error("No field path for given name {0}")]
164 NoFieldPath(String),
165}
166
167/// Errors related to string table operations.
168#[derive(thiserror::Error, Debug)]
169pub enum StringTableError {
170 /// String table not found with the given ID
171 #[error("String table not found for the given id {0}")]
172 TableNotFoundById(i32),
173
174 /// String table not found with the given name
175 #[error("String table not found for the given name {0}")]
176 TableNotFoundByName(String),
177
178 /// String table row not found at the given index
179 #[error("String table entry not found for the given index {0} ({1})")]
180 RowNotFoundByIndex(i32, String),
181}
182
183/// Errors related to combat log operations (Dota 2 only).
184#[derive(thiserror::Error, Debug)]
185pub enum CombatLogError {
186 /// Missing property in combat log entry
187 #[error("No {0} for {1}")]
188 EmptyProperty(String, String),
189 /// Missing name in combat log entry
190 #[error("No {0} for {1}")]
191 EmptyName(String, String),
192}