Files
go-jdenticon/jdenticon/errors.go
Kevin McIntyre d9e84812ff Initial release: Go Jdenticon library v0.1.0
- Core library with SVG and PNG generation
- CLI tool with generate and batch commands
- Cross-platform path handling for Windows compatibility
- Comprehensive test suite with integration tests
2026-01-03 23:41:48 -05:00

193 lines
6.0 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package jdenticon
import (
"fmt"
)
// Error types for structured error handling following Go best practices.
// ErrInvalidInput represents an error due to invalid input parameters.
type ErrInvalidInput struct {
Field string // The field or parameter that was invalid
Value string // The invalid value (may be truncated for display)
Reason string // Human-readable explanation of why it's invalid
}
func (e *ErrInvalidInput) Error() string {
if e.Field != "" {
return fmt.Sprintf("jdenticon: invalid input for %s: %s (got: %s)", e.Field, e.Reason, e.Value)
}
return fmt.Sprintf("jdenticon: invalid input: %s", e.Reason)
}
// NewErrInvalidInput creates a new ErrInvalidInput.
func NewErrInvalidInput(field, value, reason string) *ErrInvalidInput {
return &ErrInvalidInput{
Field: field,
Value: value,
Reason: reason,
}
}
// ErrInvalidSize represents an error due to invalid size parameter.
type ErrInvalidSize int
func (e ErrInvalidSize) Error() string {
return fmt.Sprintf("jdenticon: invalid size: must be positive, got %d", int(e))
}
// ErrInvalidIcon represents an error due to invalid icon state.
type ErrInvalidIcon string
func (e ErrInvalidIcon) Error() string {
return fmt.Sprintf("jdenticon: invalid icon: %s", string(e))
}
// ErrRenderFailed represents an error during rendering.
type ErrRenderFailed struct {
Format string // The format being rendered (SVG, PNG)
Cause error // The underlying error
}
func (e *ErrRenderFailed) Error() string {
return fmt.Sprintf("jdenticon: %s rendering failed: %v", e.Format, e.Cause)
}
func (e *ErrRenderFailed) Unwrap() error {
return e.Cause
}
// NewErrRenderFailed creates a new ErrRenderFailed.
func NewErrRenderFailed(format string, cause error) *ErrRenderFailed {
return &ErrRenderFailed{
Format: format,
Cause: cause,
}
}
// ErrGenerationFailed represents an error during identicon generation.
type ErrGenerationFailed struct {
Input string // The input string that failed to generate (may be truncated)
Size int // The requested size
Cause error // The underlying error
}
func (e *ErrGenerationFailed) Error() string {
return fmt.Sprintf("jdenticon: generation failed for input %q (size %d): %v", e.Input, e.Size, e.Cause)
}
func (e *ErrGenerationFailed) Unwrap() error {
return e.Cause
}
// NewErrGenerationFailed creates a new ErrGenerationFailed.
func NewErrGenerationFailed(input string, size int, cause error) *ErrGenerationFailed {
// Truncate long inputs for display
displayInput := input
if len(input) > 50 {
displayInput = input[:47] + "..."
}
return &ErrGenerationFailed{
Input: displayInput,
Size: size,
Cause: cause,
}
}
// ErrCacheCreationFailed represents an error during cache creation.
type ErrCacheCreationFailed struct {
Size int // The requested cache size
Cause error // The underlying error
}
func (e *ErrCacheCreationFailed) Error() string {
return fmt.Sprintf("jdenticon: cache creation failed (size %d): %v", e.Size, e.Cause)
}
func (e *ErrCacheCreationFailed) Unwrap() error {
return e.Cause
}
// NewErrCacheCreationFailed creates a new ErrCacheCreationFailed.
func NewErrCacheCreationFailed(size int, cause error) *ErrCacheCreationFailed {
return &ErrCacheCreationFailed{
Size: size,
Cause: cause,
}
}
// ErrValueTooLarge is returned when a numeric input exceeds a configured limit.
// This supports the configurable DoS protection system.
type ErrValueTooLarge struct {
ParameterName string // The name of the parameter being validated (e.g., "IconSize", "InputLength")
Limit int // The configured limit that was exceeded
Actual int // The actual value that was provided
}
func (e *ErrValueTooLarge) Error() string {
return fmt.Sprintf("jdenticon: %s of %d exceeds configured limit of %d",
e.ParameterName, e.Actual, e.Limit)
}
// NewErrValueTooLarge creates a new ErrValueTooLarge.
func NewErrValueTooLarge(parameterName string, limit, actual int) *ErrValueTooLarge {
return &ErrValueTooLarge{
ParameterName: parameterName,
Limit: limit,
Actual: actual,
}
}
// ErrEffectiveSizeTooLarge is returned when the effective PNG size (size * supersampling) exceeds limits.
// This provides specific context for PNG rendering with supersampling.
type ErrEffectiveSizeTooLarge struct {
Limit int // The configured size limit
Actual int // The calculated effective size (size * supersampling)
Size int // The requested icon size
Supersampling int // The supersampling factor applied
}
func (e *ErrEffectiveSizeTooLarge) Error() string {
return fmt.Sprintf("jdenticon: effective PNG size of %d (size %d × supersampling %d) exceeds limit of %d",
e.Actual, e.Size, e.Supersampling, e.Limit)
}
// NewErrEffectiveSizeTooLarge creates a new ErrEffectiveSizeTooLarge.
func NewErrEffectiveSizeTooLarge(limit, actual, size, supersampling int) *ErrEffectiveSizeTooLarge {
return &ErrEffectiveSizeTooLarge{
Limit: limit,
Actual: actual,
Size: size,
Supersampling: supersampling,
}
}
// ErrComplexityLimitExceeded is returned when the calculated geometric complexity exceeds the configured limit.
// This prevents resource exhaustion attacks through extremely complex identicon generation.
type ErrComplexityLimitExceeded struct {
Limit int // The configured complexity limit
Actual int // The calculated complexity score
InputHash string // The input hash that caused the high complexity (truncated for display)
}
func (e *ErrComplexityLimitExceeded) Error() string {
return fmt.Sprintf("jdenticon: complexity score of %d exceeds limit of %d for input hash %s",
e.Actual, e.Limit, e.InputHash)
}
// NewErrComplexityLimitExceeded creates a new ErrComplexityLimitExceeded.
func NewErrComplexityLimitExceeded(limit, actual int, inputHash string) *ErrComplexityLimitExceeded {
// Truncate long hash for display
displayHash := inputHash
if len(inputHash) > 16 {
displayHash = inputHash[:13] + "..."
}
return &ErrComplexityLimitExceeded{
Limit: limit,
Actual: actual,
InputHash: displayHash,
}
}