fyrox_impl/plugin/
error.rs1use crate::{
24 asset::state::LoadError,
25 core::{dyntype::DynTypeError, pool::PoolError, visitor::error::VisitError},
26 scene::graph::GraphError,
27};
28use std::{
29 backtrace::Backtrace,
30 fmt::{Debug, Display, Formatter},
31 sync::atomic::{AtomicBool, Ordering},
32};
33
34static CAPTURE_BACKTRACE: AtomicBool = AtomicBool::new(false);
35
36pub fn enable_backtrace_capture(capture: bool) {
39 CAPTURE_BACKTRACE.store(capture, Ordering::Relaxed);
40}
41
42pub fn is_capturing_backtrace() -> bool {
44 CAPTURE_BACKTRACE.load(Ordering::Relaxed)
45}
46
47pub enum GameErrorKind {
49 GraphError(GraphError),
51 PoolError(PoolError),
53 UserError(UserError),
55 VisitError(VisitError),
57 ResourceLoadError(LoadError),
59 DynTypeError(DynTypeError),
61 StringError(String),
63}
64
65pub struct GameError {
67 pub kind: GameErrorKind,
69 pub trace: Option<Backtrace>,
71}
72
73impl GameError {
74 pub fn new(kind: GameErrorKind) -> Self {
76 Self {
77 kind,
78 trace: if is_capturing_backtrace() {
79 Some(Backtrace::force_capture())
80 } else {
81 None
82 },
83 }
84 }
85
86 pub fn user(value: impl std::error::Error + 'static) -> Self {
88 Self::new(GameErrorKind::UserError(Box::new(value)))
89 }
90
91 pub fn str(value: impl AsRef<str>) -> Self {
93 Self::new(GameErrorKind::StringError(value.as_ref().to_string()))
94 }
95}
96
97impl From<GraphError> for GameError {
98 fn from(value: GraphError) -> Self {
99 Self::new(GameErrorKind::GraphError(value))
100 }
101}
102
103impl From<PoolError> for GameError {
104 fn from(value: PoolError) -> Self {
105 Self::new(GameErrorKind::PoolError(value))
106 }
107}
108
109impl From<UserError> for GameError {
110 fn from(value: UserError) -> Self {
111 Self::new(GameErrorKind::UserError(value))
112 }
113}
114
115impl From<LoadError> for GameError {
116 fn from(value: LoadError) -> Self {
117 Self::new(GameErrorKind::ResourceLoadError(value))
118 }
119}
120
121impl From<VisitError> for GameError {
122 fn from(value: VisitError) -> Self {
123 Self::new(GameErrorKind::VisitError(value))
124 }
125}
126
127impl From<DynTypeError> for GameError {
128 fn from(value: DynTypeError) -> Self {
129 Self::new(GameErrorKind::DynTypeError(value))
130 }
131}
132
133impl std::error::Error for GameError {}
134
135impl Display for GameError {
136 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
137 match self.trace.as_ref() {
138 Some(trace) => {
139 write!(f, "{}\nBacktrace:\n{}", self.kind, trace)
140 }
141 None => {
142 write!(
143 f,
144 "{}\nBacktrace is unavailable, call `enable_backtrace_capture(true)` to \
145 enable backtrace capture. Keep in mind that it may be very slow!",
146 self.kind
147 )
148 }
149 }
150 }
151}
152
153impl Display for GameErrorKind {
154 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
155 match self {
156 Self::GraphError(err) => Display::fmt(&err, f),
157 Self::PoolError(err) => Display::fmt(&err, f),
158 Self::UserError(err) => Display::fmt(&err, f),
159 Self::ResourceLoadError(err) => Display::fmt(&err, f),
160 Self::VisitError(err) => Display::fmt(&err, f),
161 Self::DynTypeError(err) => Display::fmt(&err, f),
162 Self::StringError(msg) => {
163 write!(f, "{msg}")
164 }
165 }
166 }
167}
168
169impl Debug for GameError {
170 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
171 write!(f, "{}", self)
172 }
173}
174
175pub type GameResult = Result<(), GameError>;
177
178pub type UserError = Box<dyn std::error::Error>;