107 lines
2.6 KiB
Go
107 lines
2.6 KiB
Go
package common
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
)
|
|
|
|
type GeminiError struct {
|
|
Msg string
|
|
Code int
|
|
Header string
|
|
}
|
|
|
|
func (e *GeminiError) Error() string {
|
|
return fmt.Sprintf("%s: %s", e.Msg, e.Header)
|
|
}
|
|
|
|
func NewErrGeminiStatusCode(code int, header string) error {
|
|
var msg string
|
|
switch {
|
|
case code >= 10 && code < 20:
|
|
msg = "needs input"
|
|
case code >= 30 && code < 40:
|
|
msg = "redirect"
|
|
case code >= 40 && code < 50:
|
|
msg = "bad request"
|
|
case code >= 50 && code < 60:
|
|
msg = "server error"
|
|
case code >= 60 && code < 70:
|
|
msg = "TLS error"
|
|
default:
|
|
msg = "unexpected Status code"
|
|
}
|
|
return &GeminiError{
|
|
Msg: msg,
|
|
Code: code,
|
|
Header: header,
|
|
}
|
|
}
|
|
|
|
var (
|
|
ErrGeminiRobotsParse = errors.New("gemini robots.txt parse error")
|
|
ErrGeminiRobotsDisallowed = errors.New("gemini robots.txt disallowed")
|
|
ErrGeminiResponseHeader = errors.New("gemini response header error")
|
|
ErrGeminiRedirect = errors.New("gemini redirection error")
|
|
ErrGeminiLinkLineParse = errors.New("gemini link line parse error")
|
|
|
|
ErrURLParse = errors.New("URL parse error")
|
|
ErrURLNotGemini = errors.New("not a Gemini URL")
|
|
ErrURLDecode = errors.New("URL decode error")
|
|
ErrUTF8Parse = errors.New("UTF-8 parse error")
|
|
ErrTextParse = errors.New("text parse error")
|
|
|
|
ErrBlacklistMatches = errors.New("url matches blacklist")
|
|
|
|
ErrNetwork = errors.New("network error")
|
|
ErrNetworkDNS = errors.New("network DNS error")
|
|
ErrNetworkTLS = errors.New("network TLS error")
|
|
ErrNetworkSetConnectionDeadline = errors.New("network error - cannot set connection deadline")
|
|
ErrNetworkCannotWrite = errors.New("network error - cannot write")
|
|
ErrNetworkResponseSizeExceededMax = errors.New("network error - response size exceeded maximum size")
|
|
|
|
ErrDatabase = errors.New("database error")
|
|
ErrDatabaseScan = errors.New("database scan error")
|
|
)
|
|
|
|
// We could have used a map for speed, but
|
|
// we would lose ability to check wrapped
|
|
// errors via errors.Is().
|
|
|
|
var errGemini *GeminiError
|
|
|
|
var knownErrors = []error{ //nolint:gochecknoglobals
|
|
errGemini,
|
|
ErrGeminiLinkLineParse,
|
|
ErrGeminiRobotsParse,
|
|
ErrGeminiRobotsDisallowed,
|
|
ErrGeminiResponseHeader,
|
|
ErrGeminiRedirect,
|
|
|
|
ErrBlacklistMatches,
|
|
|
|
ErrURLParse,
|
|
ErrURLDecode,
|
|
ErrUTF8Parse,
|
|
ErrTextParse,
|
|
|
|
ErrNetwork,
|
|
ErrNetworkDNS,
|
|
ErrNetworkTLS,
|
|
ErrNetworkSetConnectionDeadline,
|
|
ErrNetworkCannotWrite,
|
|
ErrNetworkResponseSizeExceededMax,
|
|
|
|
ErrDatabase,
|
|
ErrDatabaseScan,
|
|
}
|
|
|
|
func IsKnownError(err error) bool {
|
|
for _, known := range knownErrors {
|
|
if errors.Is(err, known) {
|
|
return true
|
|
}
|
|
}
|
|
return errors.As(err, new(*GeminiError))
|
|
}
|