Exceptions Reference¶
CMDx defines a clear exception hierarchy for distinguishing between different failure types. Understanding this hierarchy is essential for writing correct rescue clauses.
Hierarchy¶
StandardError
└── CMDx::Error (alias: CMDx::Exception)
├── CMDx::CoercionError
├── CMDx::DeprecationError
├── CMDx::UndefinedMethodError
├── CMDx::ValidationError
└── CMDx::Fault
├── CMDx::SkipFault
└── CMDx::FailFault
Interrupt
└── CMDx::TimeoutError
Exception Types¶
CMDx::Error¶
Base class for all CMDx exceptions. Also aliased as CMDx::Exception.
CMDx::CoercionError¶
Raised internally when a type coercion fails. Custom coercions must raise this to integrate with CMDx's error reporting.
class MoneyCoercion
def self.call(value, options = {})
Money.parse(value)
rescue ArgumentError
raise CMDx::CoercionError, "could not convert into money"
end
end
CMDx::ValidationError¶
Raised internally when a custom validator rejects a value. Custom validators must raise this to integrate with CMDx's error reporting.
class PhoneValidator
def self.call(value, options = {})
unless value.match?(/\A\+?[\d\s\-()]+\z/)
raise CMDx::ValidationError, "is not a valid phone number"
end
end
end
CMDx::DeprecationError¶
Raised when a task with settings(deprecate: :raise) is executed. See Deprecation.
begin
LegacyTask.execute(data: payload)
rescue CMDx::DeprecationError => e
puts "Task prohibited: #{e.message}"
end
CMDx::UndefinedMethodError¶
Raised when a task is executed without defining a work method.
class IncompleteTask < CMDx::Task
# No `work` method
end
IncompleteTask.execute #=> raises CMDx::UndefinedMethodError
CMDx::Fault¶
Base class for execution interruptions raised by execute!. All faults carry a result with full execution context. See Faults for advanced matching.
| Subclass | Triggered By | Raised When |
|---|---|---|
CMDx::SkipFault |
skip! |
Task was intentionally skipped |
CMDx::FailFault |
fail!, validation errors, exceptions |
Task execution failed |
begin
MyTask.execute!(args)
rescue CMDx::FailFault => e
e.result #=> CMDx::Result with full execution data
e.task #=> The task instance
e.context #=> Task context
e.chain #=> Execution chain
rescue CMDx::SkipFault => e
e.result.reason #=> "Reason for skipping"
rescue CMDx::Fault => e
# Catch-all for any interruption
end
CMDx::TimeoutError¶
Raised by the Timeout middleware when a task exceeds its time limit.
Caution
TimeoutError inherits from Interrupt, not StandardError. This means rescue StandardError will not catch timeouts. You must rescue CMDx::TimeoutError or Interrupt explicitly.
begin
SlowTask.execute!(data: large_dataset)
rescue CMDx::TimeoutError => e
puts "Task timed out: #{e.message}"
rescue CMDx::FailFault => e
# Timeouts caught by `execute` are wrapped in a FailFault
puts "Task failed: #{e.result.reason}"
end
Note
When using non-bang execute, timeouts are caught internally and converted to a failed result. The TimeoutError distinction matters primarily for execute! or custom middleware error handling.