package ux import ( "fmt" "strings" ) // ErrorType represents different categories of errors type ErrorType string const ( ErrorTypeConfig ErrorType = "configuration" ErrorTypePackage ErrorType = "package_management" ErrorTypeContainer ErrorType = "container" ErrorTypeManifest ErrorType = "manifest_generation" ErrorTypeFilesystem ErrorType = "filesystem" ErrorTypeNetwork ErrorType = "network" ErrorTypePermission ErrorType = "permission" ErrorTypeValidation ErrorType = "validation" ErrorTypeDependency ErrorType = "dependency" ErrorTypeBuild ErrorType = "build" ) // UserError represents a user-friendly error with context and suggestions type UserError struct { Type ErrorType Message string Context string Suggestion string OriginalErr error HelpURL string } func (e *UserError) Error() string { return e.Message } // NewUserError creates a new user-friendly error func NewUserError(errType ErrorType, message, context, suggestion string, originalErr error) *UserError { return &UserError{ Type: errType, Message: message, Context: context, Suggestion: suggestion, OriginalErr: originalErr, } } // WithHelpURL adds a help URL to the error func (e *UserError) WithHelpURL(url string) *UserError { e.HelpURL = url return e } // FormatError formats an error for user display func FormatError(err error) string { if userErr, ok := err.(*UserError); ok { return formatUserError(userErr) } return formatGenericError(err) } func formatUserError(err *UserError) string { var sb strings.Builder sb.WriteString(fmt.Sprintf("❌ %s Error: %s\n", strings.Title(string(err.Type)), err.Message)) if err.Context != "" { sb.WriteString(fmt.Sprintf(" Context: %s\n", err.Context)) } if err.Suggestion != "" { sb.WriteString(fmt.Sprintf(" 💡 Suggestion: %s\n", err.Suggestion)) } if err.HelpURL != "" { sb.WriteString(fmt.Sprintf(" 📖 Help: %s\n", err.HelpURL)) } if err.OriginalErr != nil { sb.WriteString(fmt.Sprintf(" 🔍 Technical details: %v\n", err.OriginalErr)) } return sb.String() } func formatGenericError(err error) string { return fmt.Sprintf("❌ Error: %v\n", err) } // Common error constructors for Debian-specific issues // ConfigError creates a configuration-related error func ConfigError(message string, originalErr error) *UserError { return NewUserError( ErrorTypeConfig, message, "Configuration file or settings issue", "Check your .config/registry.yaml file and ensure all required fields are present", originalErr, ).WithHelpURL("https://github.com/debian-bootc-image-builder/docs/configuration") } // PackageError creates a package management error func PackageError(message string, originalErr error) *UserError { return NewUserError( ErrorTypePackage, message, "APT package resolution or installation issue", "Ensure your system has apt-cache available and repositories are properly configured", originalErr, ).WithHelpURL("https://github.com/debian-bootc-image-builder/docs/package-management") } // ContainerError creates a container-related error func ContainerError(message string, originalErr error) *UserError { return NewUserError( ErrorTypeContainer, message, "Container image or runtime issue", "Ensure the container image exists and podman/docker is properly configured", originalErr, ).WithHelpURL("https://github.com/debian-bootc-image-builder/docs/containers") } // ManifestError creates a manifest generation error func ManifestError(message string, originalErr error) *UserError { return NewUserError( ErrorTypeManifest, message, "OSBuild manifest generation issue", "Check your package definitions and ensure all required packages are available", originalErr, ).WithHelpURL("https://github.com/debian-bootc-image-builder/docs/manifest-generation") } // FilesystemError creates a filesystem-related error func FilesystemError(message string, originalErr error) *UserError { return NewUserError( ErrorTypeFilesystem, message, "Filesystem or disk operation issue", "Check available disk space and filesystem permissions", originalErr, ).WithHelpURL("https://github.com/debian-bootc-image-builder/docs/filesystem") } // PermissionError creates a permission-related error func PermissionError(message string, originalErr error) *UserError { return NewUserError( ErrorTypePermission, message, "Insufficient permissions for operation", "Run with appropriate permissions or check file/directory ownership", originalErr, ).WithHelpURL("https://github.com/debian-bootc-image-builder/docs/permissions") } // ValidationError creates a validation error func ValidationError(message string, originalErr error) *UserError { return NewUserError( ErrorTypeValidation, message, "Input validation failed", "Check your command line arguments and configuration values", originalErr, ).WithHelpURL("https://github.com/debian-bootc-image-builder/docs/validation") } // DependencyError creates a dependency error func DependencyError(message string, originalErr error) *UserError { return NewUserError( ErrorTypeDependency, message, "Missing or incompatible dependency", "Install required dependencies or check version compatibility", originalErr, ).WithHelpURL("https://github.com/debian-bootc-image-builder/docs/dependencies") } // BuildError creates a build process error func BuildError(message string, originalErr error) *UserError { return NewUserError( ErrorTypeBuild, message, "Image build process failed", "Check build logs and ensure all prerequisites are met", originalErr, ).WithHelpURL("https://github.com/debian-bootc-image-builder/docs/build-process") }