Error Handling
Guidelines and patterns for error handling in Divekit.
The project implements a structured error handling system that distinguishes between critical and non-critical errors. This pattern is currently implemented in the distribute
package and can serve as a template for other packages.
Error Pattern
Each package can define its own error types and handling behavior. The pattern consists of:
- A custom error type that implements the
error
interface - Specific error types as constants
- Methods to determine error severity and behavior
Example from the distribute package:
// Custom error type
type CustomError struct {
ErrorType ErrorType
Message string
Err error
}
// Error types
const (
// Critical errors that lead to termination
ErrConfigLoad // Configuration loading errors
ErrWorkingDir // Working directory access errors
// Non-critical errors that trigger warnings
ErrMembersNotFound // Member lookup failures
)
Example Implementation
Here’s how to implement this pattern in your package:
// Create a new error
if err := loadConfig(); err != nil {
return NewCustomError(ErrConfigLoad, "failed to load configuration", err)
}
// Handle non-critical errors
if err := validateData(); err != nil {
if !err.IsCritical() {
log.Warn(err.Error())
// Continue execution...
} else {
return err
}
}
Error Behavior
Each package can define its own error behavior, but should follow these general principles:
- Critical Errors: Should terminate the current operation
- Non-Critical Errors: Should generate warnings but allow continuation
- Wrapped Errors: Should preserve the original error context
Each error should include:
- An error type indicating its severity
- A descriptive message
- The original error (if applicable)
- A method to determine if it’s critical
This pattern provides consistent error handling while remaining flexible enough to accommodate different package requirements. The distribute
package provides a reference implementation of this pattern.
Last modified January 17, 2025: refactor more (5c372af)