feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output, top-level run/workflow aliases matching gh CLI structure. Enhance actions, issues, PRs, releases, repos, labels, milestones, and wiki commands with improved flags, JSON output, and error handling.
This commit is contained in:
parent
7c0dcc8696
commit
113505de95
29 changed files with 3131 additions and 542 deletions
|
|
@ -3,7 +3,8 @@ package cmd
|
|||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"os"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"forgejo.zerova.net/sid/fgj-sid/internal/api"
|
||||
)
|
||||
|
|
@ -40,6 +41,45 @@ func NewAPIError(status int, message string) *CLIError {
|
|||
return &CLIError{Code: ErrAPIError, Message: message, Status: status}
|
||||
}
|
||||
|
||||
// ContextualError wraps common errors with helpful hints.
|
||||
func ContextualError(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
msg := err.Error()
|
||||
|
||||
// Check for API errors with status codes
|
||||
var apiErr *api.APIError
|
||||
if errors.As(err, &apiErr) {
|
||||
switch {
|
||||
case apiErr.StatusCode == 401 || apiErr.StatusCode == 403:
|
||||
return fmt.Errorf("%w\nHint: Try authenticating with: fgj auth login", err)
|
||||
case apiErr.StatusCode == 404:
|
||||
return fmt.Errorf("%w\nHint: Resource not found. Check the repository and number are correct.", err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Check for network/connection errors
|
||||
switch {
|
||||
case strings.Contains(msg, "no such host"):
|
||||
return fmt.Errorf("%w\nHint: Check your internet connection and that the host is correct.", err)
|
||||
case strings.Contains(msg, "connection refused"):
|
||||
return fmt.Errorf("%w\nHint: Check your internet connection and that the host is correct.", err)
|
||||
}
|
||||
|
||||
// Check for string-based status code patterns (from wrapped errors)
|
||||
switch {
|
||||
case strings.Contains(msg, "401") || strings.Contains(msg, "403"):
|
||||
if strings.Contains(msg, "authentication") || strings.Contains(msg, "unauthorized") || strings.Contains(msg, "forbidden") {
|
||||
return fmt.Errorf("%w\nHint: Try authenticating with: fgj auth login", err)
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// writeJSONError writes a structured JSON error to stderr.
|
||||
// It attempts to extract structured info from known error types.
|
||||
// WriteJSONError writes a structured JSON error to stderr.
|
||||
|
|
@ -70,7 +110,7 @@ func WriteJSONError(err error) {
|
|||
}
|
||||
}
|
||||
|
||||
enc := json.NewEncoder(os.Stderr)
|
||||
enc := json.NewEncoder(ios.ErrOut)
|
||||
enc.SetIndent("", " ")
|
||||
_ = enc.Encode(cliErr)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue