1use std::fmt::Display;
2
3use crate::enums::ObsResetVideoStatus;
4
5#[derive(Clone, Debug, PartialEq, Eq)]
7pub enum ObsError {
8 Failure,
10 InvalidDll,
12 MutexFailure,
15 ThreadFailure,
17 ResetAudioFailure,
19 ResetVideoFailure(ObsResetVideoStatus),
21 ResetVideoFailureGraphicsModule,
24 ResetVideoFailureOutputActive,
26 NullPointer(Option<String>),
30 OutputAlreadyActive,
31 OutputStartFailure(Option<String>),
32 OutputStopFailure(Option<String>),
33 OutputPauseFailure(Option<String>),
34 OutputNotFound,
35 SourceNotFound,
36 SourceNotAvailable(String),
37 InvalidOperation(String),
38 StringConversionError,
40
41 DisplayCreationError(String),
43
44 OutputSaveBufferFailure(String),
45
46 InvocationError(String),
48
49 JsonParseError,
50 NoSenderError,
52 NoAvailableEncoders,
53 LockError(String),
55 Unexpected(String),
56
57 EncoderActive,
59
60 PlatformInitError(String),
62
63 IoError(String),
65
66 SignalDataError(String),
68
69 EnumConversionError(String),
71
72 PropertyTypeMismatch {
74 expected: String,
75 },
76
77 PropertyNotFound {
79 name: String,
80 },
81
82 PropertyValueTypeMismatch {
84 name: String,
85 expected: String,
86 actual: String,
87 },
88
89 PropertyValueOutOfRange {
91 name: String,
92 value: String,
93 min: String,
94 max: String,
95 },
96
97 PropertyValueNotAllowed {
99 name: String,
100 value: String,
101 },
102
103 PropertyValueUnsupported {
105 name: String,
106 property_type: String,
107 },
108
109 RuntimeChannelError(String),
111
112 RuntimeQueueFull {
114 capacity: usize,
115 },
116
117 RuntimePanicked,
119
120 RuntimeMismatch,
122
123 CapabilityKindMismatch {
125 id: String,
126 expected: String,
127 actual: String,
128 },
129
130 OutputPipelineMissingComponent {
132 output_id: String,
133 component: String,
134 },
135
136 OutputPipelineUnexpectedComponent {
138 output_id: String,
139 component: String,
140 },
141
142 OutputPipelineUnsupportedCodec {
144 output_id: String,
145 media: String,
146 codec: String,
147 },
148
149 OutputPipelineUnsupportedProtocol {
151 output_id: String,
152 protocol: String,
153 },
154
155 NoCompatibleOutputGraph {
157 summary: String,
158 },
159
160 AudioMixerIndexOutOfBounds {
162 index: usize,
163 max: usize,
164 },
165
166 RuntimeReentrantBlocking,
168
169 RuntimeOutsideThread,
173
174 FilterAlreadyApplied,
176}
177
178#[cfg_attr(coverage_nightly, coverage(off))]
179impl Display for ObsError {
180 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
181 write!(f, "OBS Error: ")?;
182
183 match self {
184 ObsError::Failure => write!(f, "`obs-startup` function failed on libobs"),
185 ObsError::MutexFailure => write!(f, "Failed to lock mutex describing whether there is a thread using libobs or not. Report to crate maintainer."),
186 ObsError::ThreadFailure => write!(f, "Some or no thread is already using libobs. This is a bug!"),
187 ObsError::ResetAudioFailure => write!(f, "Could not initialize/reset OBS audio."),
188 ObsError::ResetVideoFailure(status) => write!(f, "Could not reset obs video. Status: {:?}", status),
189 ObsError::ResetVideoFailureGraphicsModule => write!(f, "Unable to reset video because the program attempted to change the graphics module. This is a bug!"),
190 ObsError::ResetVideoFailureOutputActive => write!(f, "Unable to reset video because some outputs were still active."),
191 ObsError::NullPointer(e) => write!(f, "The function returned a null pointer, often indicating an error with creating the object of the requested pointer. Details: {:?}", e),
192 ObsError::OutputAlreadyActive => write!(f, "Output is already active."),
193 ObsError::OutputStartFailure(s) => write!(f, "Output failed to start. Error is {:?}", s),
194 ObsError::OutputStopFailure(s) => write!(f, "Output failed to stop. Error is {:?}", s),
195 ObsError::OutputNotFound => write!(f, "Output not found."),
196 ObsError::DisplayCreationError(e) => write!(f, "Native error from the Windows API when creating a display: {:?}", e),
197 ObsError::OutputSaveBufferFailure(e) => write!(f, "Couldn't save output buffer: {:?}", e),
198 ObsError::SourceNotFound => write!(f, "Source not found."),
199 ObsError::SourceNotAvailable(source_name) => write!(f, "Source {} is not available. See logs or similar to check why.", source_name),
200 ObsError::InvocationError(e) => write!(f, "The obs thread couldn't be called: {:?}", e),
201 ObsError::JsonParseError => write!(f, "Failed to parse JSON data."),
202 ObsError::NoSenderError => write!(f, "Couldn't get the sender of the signal."),
203 ObsError::NoAvailableEncoders => write!(f, "No available encoders found."),
204 ObsError::OutputPauseFailure(s) => write!(f, "Output failed to pause. Error is {:?}", s),
205 ObsError::LockError(e) => write!(f, "Error locking a mutex or RwLock: {:?}. You should probably restart the application to avoid memory leaks.", e),
206 ObsError::Unexpected(e) => write!(f, "Unexpected error: {:?}", e),
207 ObsError::EncoderActive => write!(f, "Encoder is still active, stop the attached output before proceeding"),
208 ObsError::StringConversionError => write!(f, "Error converting a string between Rust and OBS"),
209 ObsError::PlatformInitError(e) => write!(f, "Error during platform-specific initialization: {}", e),
210 ObsError::InvalidOperation(e) => write!(f, "Invalid operation: {}", e),
211 ObsError::IoError(e) => write!(f, "I/O error: {}", e),
212 ObsError::SignalDataError(e) => write!(f, "Signal data error: {}", e),
213 ObsError::EnumConversionError(e) => write!(f, "Enum conversion error: {}", e),
214 ObsError::PropertyTypeMismatch { expected } => write!(f, "OBS property type mismatch; expected {expected}"),
215 ObsError::PropertyNotFound { name } => write!(f, "OBS settings schema has no property named '{name}'."),
216 ObsError::PropertyValueTypeMismatch { name, expected, actual } => write!(f, "OBS property '{name}' expects {expected}, but received {actual}."),
217 ObsError::PropertyValueOutOfRange { name, value, min, max } => write!(f, "OBS property '{name}' value {value} is outside the supported range {min}..={max}."),
218 ObsError::PropertyValueNotAllowed { name, value } => write!(f, "OBS property '{name}' does not accept value {value}."),
219 ObsError::PropertyValueUnsupported { name, property_type } => write!(f, "OBS property '{name}' ({property_type}) is not a scalar setting value."),
220 ObsError::RuntimeChannelError(e) => write!(f, "Runtime channel error: {}", e),
221 ObsError::RuntimeQueueFull { capacity } => write!(f, "OBS runtime queue is full (capacity: {}). Batch work or retry later.", capacity),
222 ObsError::RuntimePanicked => write!(f, "The OBS actor panicked and has been shut down."),
223 ObsError::RuntimeMismatch => write!(f, "The operation mixed objects owned by different OBS runtimes."),
224 ObsError::CapabilityKindMismatch { id, expected, actual } => write!(f, "Discovered OBS type '{id}' has kind '{actual}', but this operation requires '{expected}'."),
225 ObsError::OutputPipelineMissingComponent { output_id, component } => write!(f, "Output pipeline for '{output_id}' requires {component}."),
226 ObsError::OutputPipelineUnexpectedComponent { output_id, component } => write!(f, "Output pipeline for '{output_id}' does not accept {component}."),
227 ObsError::OutputPipelineUnsupportedCodec { output_id, media, codec } => write!(f, "Output '{output_id}' does not support {media} codec '{codec}'."),
228 ObsError::OutputPipelineUnsupportedProtocol { output_id, protocol } => write!(f, "Output '{output_id}' does not support service protocol '{protocol}'."),
229 ObsError::NoCompatibleOutputGraph { summary } => write!(f, "No compatible OBS output graph: {summary}"),
230 ObsError::AudioMixerIndexOutOfBounds { index, max } => write!(f, "Audio mixer index {index} is out of bounds (max {max})."),
231 ObsError::RuntimeReentrantBlocking => write!(f, "A blocking operation cannot wait for an OBS callback from the OBS actor thread."),
232 ObsError::InvalidDll => write!(f, "A dummy DLL was loaded instead of the real libobs DLL. Make sure you bootstrap properly with libobs-bootstrapper"),
233 #[cfg(feature="enable_runtime")]
234 ObsError::RuntimeOutsideThread => write!(f, "Attempted to call a OBS runtime function from outside the OBS thread. This is a bug in the crate!"),
235 #[cfg(not(feature="enable_runtime"))]
236 ObsError::RuntimeOutsideThread => write!(f, "Attempted to call a OBS runtime function from outside the OBS thread. Make sure that you do not use any OBS struct from a different thread than the one where the ObsContext was initialized. THIS BUG WILL CAUSE MEMORY CORRUPTION OR DEADLOCKS!"),
237 ObsError::FilterAlreadyApplied => write!(f, "Filter was applied already."),
238 }
239 }
240}
241
242impl std::error::Error for ObsError {}