mirror of
https://github.com/aykhans/sarin.git
synced 2026-02-28 06:49:13 +00:00
Introduce structured error types and bump Go/linter versions
Replace ad-hoc fmt.Errorf/errors.New calls with typed error structs across config, sarin, and script packages to enable type-based error handling. Add script-specific error handlers in CLI entry point. Fix variable shadowing bug in Worker for scriptTransformer. Bump Go to 1.25.7 and golangci-lint to v2.8.0.
This commit is contained in:
@@ -6,16 +6,12 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
// General
|
||||
ErrNoError = errors.New("no error (internal)")
|
||||
|
||||
// CLI
|
||||
ErrCLINoArgs = errors.New("CLI expects arguments but received none")
|
||||
)
|
||||
|
||||
// ======================================== General ========================================
|
||||
|
||||
var (
|
||||
ErrNoError = errors.New("no error (internal)")
|
||||
)
|
||||
|
||||
type FieldParseError struct {
|
||||
Field string
|
||||
Value string
|
||||
@@ -131,8 +127,147 @@ func (e UnmarshalError) Unwrap() error {
|
||||
return e.error
|
||||
}
|
||||
|
||||
// ======================================== General I/O ========================================
|
||||
|
||||
type FileReadError struct {
|
||||
Path string
|
||||
Err error
|
||||
}
|
||||
|
||||
func NewFileReadError(path string, err error) FileReadError {
|
||||
if err == nil {
|
||||
err = ErrNoError
|
||||
}
|
||||
return FileReadError{path, err}
|
||||
}
|
||||
|
||||
func (e FileReadError) Error() string {
|
||||
return fmt.Sprintf("failed to read file %s: %v", e.Path, e.Err)
|
||||
}
|
||||
|
||||
func (e FileReadError) Unwrap() error {
|
||||
return e.Err
|
||||
}
|
||||
|
||||
type HTTPFetchError struct {
|
||||
URL string
|
||||
Err error
|
||||
}
|
||||
|
||||
func NewHTTPFetchError(url string, err error) HTTPFetchError {
|
||||
if err == nil {
|
||||
err = ErrNoError
|
||||
}
|
||||
return HTTPFetchError{url, err}
|
||||
}
|
||||
|
||||
func (e HTTPFetchError) Error() string {
|
||||
return fmt.Sprintf("failed to fetch %s: %v", e.URL, e.Err)
|
||||
}
|
||||
|
||||
func (e HTTPFetchError) Unwrap() error {
|
||||
return e.Err
|
||||
}
|
||||
|
||||
type HTTPStatusError struct {
|
||||
URL string
|
||||
StatusCode int
|
||||
Status string
|
||||
}
|
||||
|
||||
func NewHTTPStatusError(url string, statusCode int, status string) HTTPStatusError {
|
||||
return HTTPStatusError{url, statusCode, status}
|
||||
}
|
||||
|
||||
func (e HTTPStatusError) Error() string {
|
||||
return fmt.Sprintf("HTTP %d %s (url: %s)", e.StatusCode, e.Status, e.URL)
|
||||
}
|
||||
|
||||
type URLParseError struct {
|
||||
URL string
|
||||
Err error
|
||||
}
|
||||
|
||||
func NewURLParseError(url string, err error) URLParseError {
|
||||
if err == nil {
|
||||
err = ErrNoError
|
||||
}
|
||||
return URLParseError{url, err}
|
||||
}
|
||||
|
||||
func (e URLParseError) Error() string {
|
||||
return fmt.Sprintf("invalid URL %q: %v", e.URL, e.Err)
|
||||
}
|
||||
|
||||
func (e URLParseError) Unwrap() error {
|
||||
return e.Err
|
||||
}
|
||||
|
||||
// ======================================== Template ========================================
|
||||
|
||||
var (
|
||||
ErrFileCacheNotInitialized = errors.New("file cache is not initialized")
|
||||
ErrFormDataOddArgs = errors.New("body_FormData requires an even number of arguments (key-value pairs)")
|
||||
)
|
||||
|
||||
type TemplateParseError struct {
|
||||
Err error
|
||||
}
|
||||
|
||||
func NewTemplateParseError(err error) TemplateParseError {
|
||||
if err == nil {
|
||||
err = ErrNoError
|
||||
}
|
||||
return TemplateParseError{err}
|
||||
}
|
||||
|
||||
func (e TemplateParseError) Error() string {
|
||||
return "template parse error: " + e.Err.Error()
|
||||
}
|
||||
|
||||
func (e TemplateParseError) Unwrap() error {
|
||||
return e.Err
|
||||
}
|
||||
|
||||
type TemplateRenderError struct {
|
||||
Err error
|
||||
}
|
||||
|
||||
func NewTemplateRenderError(err error) TemplateRenderError {
|
||||
if err == nil {
|
||||
err = ErrNoError
|
||||
}
|
||||
return TemplateRenderError{err}
|
||||
}
|
||||
|
||||
func (e TemplateRenderError) Error() string {
|
||||
return "template rendering: " + e.Err.Error()
|
||||
}
|
||||
|
||||
func (e TemplateRenderError) Unwrap() error {
|
||||
return e.Err
|
||||
}
|
||||
|
||||
// ======================================== YAML ========================================
|
||||
|
||||
type YAMLFormatError struct {
|
||||
Detail string
|
||||
}
|
||||
|
||||
func NewYAMLFormatError(detail string) YAMLFormatError {
|
||||
return YAMLFormatError{detail}
|
||||
}
|
||||
|
||||
func (e YAMLFormatError) Error() string {
|
||||
return e.Detail
|
||||
}
|
||||
|
||||
// ======================================== CLI ========================================
|
||||
|
||||
var (
|
||||
ErrCLINoArgs = errors.New("CLI expects arguments but received none")
|
||||
)
|
||||
|
||||
type CLIUnexpectedArgsError struct {
|
||||
Args []string
|
||||
}
|
||||
@@ -168,6 +303,61 @@ func (e ConfigFileReadError) Unwrap() error {
|
||||
|
||||
// ======================================== Proxy ========================================
|
||||
|
||||
type ProxyUnsupportedSchemeError struct {
|
||||
Scheme string
|
||||
}
|
||||
|
||||
func NewProxyUnsupportedSchemeError(scheme string) ProxyUnsupportedSchemeError {
|
||||
return ProxyUnsupportedSchemeError{scheme}
|
||||
}
|
||||
|
||||
func (e ProxyUnsupportedSchemeError) Error() string {
|
||||
return "unsupported proxy scheme: " + e.Scheme
|
||||
}
|
||||
|
||||
type ProxyParseError struct {
|
||||
Err error
|
||||
}
|
||||
|
||||
func NewProxyParseError(err error) ProxyParseError {
|
||||
if err == nil {
|
||||
err = ErrNoError
|
||||
}
|
||||
return ProxyParseError{err}
|
||||
}
|
||||
|
||||
func (e ProxyParseError) Error() string {
|
||||
return "failed to parse proxy URL: " + e.Err.Error()
|
||||
}
|
||||
|
||||
func (e ProxyParseError) Unwrap() error {
|
||||
return e.Err
|
||||
}
|
||||
|
||||
type ProxyConnectError struct {
|
||||
Status string
|
||||
}
|
||||
|
||||
func NewProxyConnectError(status string) ProxyConnectError {
|
||||
return ProxyConnectError{status}
|
||||
}
|
||||
|
||||
func (e ProxyConnectError) Error() string {
|
||||
return "proxy CONNECT failed: " + e.Status
|
||||
}
|
||||
|
||||
type ProxyResolveError struct {
|
||||
Host string
|
||||
}
|
||||
|
||||
func NewProxyResolveError(host string) ProxyResolveError {
|
||||
return ProxyResolveError{host}
|
||||
}
|
||||
|
||||
func (e ProxyResolveError) Error() string {
|
||||
return "no IP addresses found for host: " + e.Host
|
||||
}
|
||||
|
||||
type ProxyDialError struct {
|
||||
Proxy string
|
||||
Err error
|
||||
@@ -187,3 +377,86 @@ func (e ProxyDialError) Error() string {
|
||||
func (e ProxyDialError) Unwrap() error {
|
||||
return e.Err
|
||||
}
|
||||
|
||||
// ======================================== Script ========================================
|
||||
|
||||
var (
|
||||
ErrScriptEmpty = errors.New("script cannot be empty")
|
||||
ErrScriptSourceEmpty = errors.New("script source cannot be empty after @")
|
||||
ErrScriptTransformMissing = errors.New("script must define a global 'transform' function")
|
||||
ErrScriptTransformReturnObject = errors.New("transform function must return an object")
|
||||
ErrScriptURLNoHost = errors.New("script URL must have a host")
|
||||
)
|
||||
|
||||
type ScriptLoadError struct {
|
||||
Source string
|
||||
Err error
|
||||
}
|
||||
|
||||
func NewScriptLoadError(source string, err error) ScriptLoadError {
|
||||
if err == nil {
|
||||
err = ErrNoError
|
||||
}
|
||||
return ScriptLoadError{source, err}
|
||||
}
|
||||
|
||||
func (e ScriptLoadError) Error() string {
|
||||
return fmt.Sprintf("failed to load script from %q: %v", e.Source, e.Err)
|
||||
}
|
||||
|
||||
func (e ScriptLoadError) Unwrap() error {
|
||||
return e.Err
|
||||
}
|
||||
|
||||
type ScriptExecutionError struct {
|
||||
EngineType string
|
||||
Err error
|
||||
}
|
||||
|
||||
func NewScriptExecutionError(engineType string, err error) ScriptExecutionError {
|
||||
if err == nil {
|
||||
err = ErrNoError
|
||||
}
|
||||
return ScriptExecutionError{engineType, err}
|
||||
}
|
||||
|
||||
func (e ScriptExecutionError) Error() string {
|
||||
return fmt.Sprintf("%s script error: %v", e.EngineType, e.Err)
|
||||
}
|
||||
|
||||
func (e ScriptExecutionError) Unwrap() error {
|
||||
return e.Err
|
||||
}
|
||||
|
||||
type ScriptChainError struct {
|
||||
EngineType string
|
||||
Index int
|
||||
Err error
|
||||
}
|
||||
|
||||
func NewScriptChainError(engineType string, index int, err error) ScriptChainError {
|
||||
if err == nil {
|
||||
err = ErrNoError
|
||||
}
|
||||
return ScriptChainError{engineType, index, err}
|
||||
}
|
||||
|
||||
func (e ScriptChainError) Error() string {
|
||||
return fmt.Sprintf("%s script[%d]: %v", e.EngineType, e.Index, e.Err)
|
||||
}
|
||||
|
||||
func (e ScriptChainError) Unwrap() error {
|
||||
return e.Err
|
||||
}
|
||||
|
||||
type ScriptUnknownEngineError struct {
|
||||
EngineType string
|
||||
}
|
||||
|
||||
func NewScriptUnknownEngineError(engineType string) ScriptUnknownEngineError {
|
||||
return ScriptUnknownEngineError{engineType}
|
||||
}
|
||||
|
||||
func (e ScriptUnknownEngineError) Error() string {
|
||||
return "unknown engine type: " + e.EngineType
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
@@ -17,6 +16,9 @@ func (proxies *Proxies) Append(proxy ...Proxy) {
|
||||
*proxies = append(*proxies, proxy...)
|
||||
}
|
||||
|
||||
// Parse parses a raw proxy string and appends it to the list.
|
||||
// It can return the following errors:
|
||||
// - ProxyParseError
|
||||
func (proxies *Proxies) Parse(rawValue string) error {
|
||||
parsedProxy, err := ParseProxy(rawValue)
|
||||
if err != nil {
|
||||
@@ -27,10 +29,13 @@ func (proxies *Proxies) Parse(rawValue string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ParseProxy parses a raw proxy URL string into a Proxy.
|
||||
// It can return the following errors:
|
||||
// - ProxyParseError
|
||||
func ParseProxy(rawValue string) (*Proxy, error) {
|
||||
urlParsed, err := url.Parse(rawValue)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse proxy URL: %w", err)
|
||||
return nil, NewProxyParseError(err)
|
||||
}
|
||||
|
||||
proxyParsed := Proxy(*urlParsed)
|
||||
|
||||
Reference in New Issue
Block a user