Implement comprehensive error types and handling
Add complete error handling system for Kanboard API client: Sentinel errors: - Network: ErrConnectionFailed, ErrTimeout - Auth: ErrUnauthorized, ErrForbidden - Resources: ErrNotFound, ErrProjectNotFound, ErrTaskNotFound, ErrColumnNotFound, ErrCommentNotFound - Logic: ErrAlreadyInLastColumn, ErrAlreadyInFirstColumn, ErrTaskClosed, ErrTaskOpen - Validation: ErrEmptyTitle, ErrInvalidProjectID Helper functions: - IsNotFound() - checks all not-found error variants - IsUnauthorized() - checks auth errors - IsAPIError() - checks for API errors via errors.As All errors support errors.Is/errors.As for proper error wrapping and context preservation. Closes: kanboard-api-s7k
This commit is contained in:
parent
ba942f3b52
commit
79385df87b
3 changed files with 289 additions and 1 deletions
69
errors.go
69
errors.go
|
|
@ -5,10 +5,17 @@ import (
|
|||
"fmt"
|
||||
)
|
||||
|
||||
// Network errors
|
||||
var (
|
||||
// ErrConnectionFailed indicates a connection to the Kanboard server failed.
|
||||
ErrConnectionFailed = errors.New("connection to Kanboard server failed")
|
||||
|
||||
// ErrTimeout indicates a request timed out.
|
||||
ErrTimeout = errors.New("request timed out")
|
||||
)
|
||||
|
||||
// Authentication errors
|
||||
var (
|
||||
// ErrUnauthorized indicates authentication failed.
|
||||
ErrUnauthorized = errors.New("authentication failed: invalid credentials")
|
||||
|
||||
|
|
@ -16,6 +23,48 @@ var (
|
|||
ErrForbidden = errors.New("access forbidden: insufficient permissions")
|
||||
)
|
||||
|
||||
// Resource errors
|
||||
var (
|
||||
// ErrNotFound indicates a resource was not found.
|
||||
ErrNotFound = errors.New("resource not found")
|
||||
|
||||
// ErrProjectNotFound indicates the specified project was not found.
|
||||
ErrProjectNotFound = errors.New("project not found")
|
||||
|
||||
// ErrTaskNotFound indicates the specified task was not found.
|
||||
ErrTaskNotFound = errors.New("task not found")
|
||||
|
||||
// ErrColumnNotFound indicates the specified column was not found.
|
||||
ErrColumnNotFound = errors.New("column not found")
|
||||
|
||||
// ErrCommentNotFound indicates the specified comment was not found.
|
||||
ErrCommentNotFound = errors.New("comment not found")
|
||||
)
|
||||
|
||||
// Logic errors
|
||||
var (
|
||||
// ErrAlreadyInLastColumn indicates a task is already in the last column.
|
||||
ErrAlreadyInLastColumn = errors.New("task is already in the last column")
|
||||
|
||||
// ErrAlreadyInFirstColumn indicates a task is already in the first column.
|
||||
ErrAlreadyInFirstColumn = errors.New("task is already in the first column")
|
||||
|
||||
// ErrTaskClosed indicates a task is already closed.
|
||||
ErrTaskClosed = errors.New("task is already closed")
|
||||
|
||||
// ErrTaskOpen indicates a task is already open.
|
||||
ErrTaskOpen = errors.New("task is already open")
|
||||
)
|
||||
|
||||
// Validation errors
|
||||
var (
|
||||
// ErrEmptyTitle indicates a task title cannot be empty.
|
||||
ErrEmptyTitle = errors.New("task title cannot be empty")
|
||||
|
||||
// ErrInvalidProjectID indicates an invalid project ID was provided.
|
||||
ErrInvalidProjectID = errors.New("invalid project ID")
|
||||
)
|
||||
|
||||
// APIError represents an error returned by the Kanboard API.
|
||||
type APIError struct {
|
||||
Code int
|
||||
|
|
@ -26,3 +75,23 @@ type APIError struct {
|
|||
func (e *APIError) Error() string {
|
||||
return fmt.Sprintf("Kanboard API error (code %d): %s", e.Code, e.Message)
|
||||
}
|
||||
|
||||
// IsNotFound returns true if the error indicates a resource was not found.
|
||||
func IsNotFound(err error) bool {
|
||||
return errors.Is(err, ErrNotFound) ||
|
||||
errors.Is(err, ErrProjectNotFound) ||
|
||||
errors.Is(err, ErrTaskNotFound) ||
|
||||
errors.Is(err, ErrColumnNotFound) ||
|
||||
errors.Is(err, ErrCommentNotFound)
|
||||
}
|
||||
|
||||
// IsUnauthorized returns true if the error indicates an authentication failure.
|
||||
func IsUnauthorized(err error) bool {
|
||||
return errors.Is(err, ErrUnauthorized)
|
||||
}
|
||||
|
||||
// IsAPIError returns true if the error is an APIError from the Kanboard API.
|
||||
func IsAPIError(err error) bool {
|
||||
var apiErr *APIError
|
||||
return errors.As(err, &apiErr)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue