js_deobfuscator/core/
error.rs

1//! Error types for the deobfuscation engine.
2
3use thiserror::Error;
4
5// ============================================================================
6// DeobError
7// ============================================================================
8
9/// Main error type for the deobfuscator.
10#[derive(Debug, Error)]
11pub enum DeobError {
12    /// Parsing failed.
13    #[error("parse error: {0}")]
14    Parse(String),
15
16    /// Transform error.
17    #[error("transform error: {0}")]
18    Transform(String),
19
20    /// Pass-specific error.
21    #[error("pass error in {pass}: {message}")]
22    Pass {
23        /// Name of the pass that failed.
24        pass: &'static str,
25        /// Error message.
26        message: String,
27    },
28
29    /// Configuration error.
30    #[error("configuration error: {0}")]
31    Config(String),
32
33    /// Max iterations reached without convergence.
34    #[error("max iterations reached without convergence")]
35    MaxIterations,
36}
37
38impl DeobError {
39    /// Create a parse error.
40    pub fn parse(message: impl Into<String>) -> Self {
41        Self::Parse(message.into())
42    }
43
44    /// Create a transform error.
45    pub fn transform(message: impl Into<String>) -> Self {
46        Self::Transform(message.into())
47    }
48
49    /// Create a pass error.
50    pub fn pass(pass: &'static str, message: impl Into<String>) -> Self {
51        Self::Pass {
52            pass,
53            message: message.into(),
54        }
55    }
56
57    /// Create a configuration error.
58    pub fn config(message: impl Into<String>) -> Self {
59        Self::Config(message.into())
60    }
61}
62
63// ============================================================================
64// PassError
65// ============================================================================
66
67/// Error from a specific pass.
68///
69/// Used for non-fatal errors that should be collected but not stop execution.
70#[derive(Debug, Clone)]
71pub struct PassError {
72    /// Name of the pass that encountered the error.
73    pub pass: &'static str,
74
75    /// Error message.
76    pub message: String,
77
78    /// Whether the error is recoverable.
79    pub recoverable: bool,
80}
81
82impl PassError {
83    /// Create a new pass error.
84    pub fn new(pass: &'static str, message: impl Into<String>) -> Self {
85        Self {
86            pass,
87            message: message.into(),
88            recoverable: true,
89        }
90    }
91
92    /// Create a non-recoverable pass error.
93    pub fn fatal(pass: &'static str, message: impl Into<String>) -> Self {
94        Self {
95            pass,
96            message: message.into(),
97            recoverable: false,
98        }
99    }
100}
101
102impl std::fmt::Display for PassError {
103    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
104        write!(f, "[{}] {}", self.pass, self.message)
105    }
106}