- Replace custom error handling with xerrors package - Enhance error descriptions for better debugging - Add text utilities for string processing - Update error tests to use standard errors package - Add String() method to GeminiError 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
65 lines
1.6 KiB
Go
65 lines
1.6 KiB
Go
package gemini
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
)
|
|
|
|
// GeminiError is used to represent
|
|
// Gemini network protocol errors only.
|
|
// Should be recorded to the snapshot.
|
|
// See https://geminiprotocol.net/docs/protocol-specification.gmi
|
|
type GeminiError struct {
|
|
Msg string
|
|
Code int
|
|
Header string
|
|
}
|
|
|
|
func (e *GeminiError) Error() string {
|
|
return fmt.Sprintf("gemini error: code %d %s", e.Code, e.Msg)
|
|
}
|
|
|
|
func (e *GeminiError) String() string {
|
|
return e.Error()
|
|
}
|
|
|
|
// NewGeminiError creates a new GeminiError based on the status code and header.
|
|
// Status codes are based on the Gemini protocol specification:
|
|
// - 1x: Input required
|
|
// - 2x: Success (not handled as errors)
|
|
// - 3x: Redirect
|
|
// - 4x: Temporary failure
|
|
// - 5x: Permanent failure
|
|
// - 6x: Client certificate required/rejected
|
|
func NewGeminiError(code int, header string) error {
|
|
var msg string
|
|
switch {
|
|
case code >= 10 && code < 20:
|
|
msg = fmt.Sprintf("input required: %s", header)
|
|
case code >= 30 && code < 40:
|
|
msg = fmt.Sprintf("redirect: %s", header)
|
|
case code >= 40 && code < 50:
|
|
msg = fmt.Sprintf("request failed: %s", header)
|
|
case code >= 50 && code < 60:
|
|
msg = fmt.Sprintf("server error: %s", header)
|
|
case code >= 60 && code < 70:
|
|
msg = fmt.Sprintf("TLS error: %s", header)
|
|
default:
|
|
msg = fmt.Sprintf("unexpected status code %d: %s", code, header)
|
|
}
|
|
return &GeminiError{
|
|
Msg: msg,
|
|
Code: code,
|
|
Header: header,
|
|
}
|
|
}
|
|
|
|
// IsGeminiError checks if the given error is a GeminiError.
|
|
func IsGeminiError(err error) bool {
|
|
if err == nil {
|
|
return false
|
|
}
|
|
var asError *GeminiError
|
|
return errors.As(err, &asError)
|
|
}
|