2025-08-21 18:26:05 +05:30
|
|
|
package ui
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"os"
|
|
|
|
|
|
|
|
|
|
"github.com/safedep/dry/log"
|
2026-05-24 12:22:19 +05:30
|
|
|
"github.com/safedep/pmg/errcodes"
|
2025-08-21 18:26:05 +05:30
|
|
|
)
|
|
|
|
|
|
2026-01-17 14:05:01 +05:30
|
|
|
// ErrorExit prints a minimal, clean error message and exits with a non-zero status code.
|
2025-08-21 18:26:05 +05:30
|
|
|
func ErrorExit(err error) {
|
2026-05-19 14:40:54 +05:30
|
|
|
ErrorExitWithCode(err, 1)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ErrorExitWithCode prints a minimal, clean error message and exits with code.
|
|
|
|
|
func ErrorExitWithCode(err error, code int) {
|
2025-08-21 18:26:05 +05:30
|
|
|
log.Errorf("Exiting due to error: %s", err)
|
|
|
|
|
|
2026-01-17 14:05:01 +05:30
|
|
|
usefulErr := convertToUsefulError(err)
|
2025-08-21 18:26:05 +05:30
|
|
|
|
|
|
|
|
ClearStatus()
|
|
|
|
|
|
2026-01-17 14:05:01 +05:30
|
|
|
// Use help as hint, but for unknown errors show bug report link
|
|
|
|
|
hint := usefulErr.Help()
|
2026-05-24 12:22:19 +05:30
|
|
|
if usefulErr.Code() == errcodes.Unknown {
|
2026-01-17 14:05:01 +05:30
|
|
|
hint = "Report this issue: https://github.com/safedep/pmg/issues/new?labels=bug"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if verbosityLevel == VerbosityLevelVerbose {
|
|
|
|
|
printVerboseError(usefulErr.Code(), usefulErr.HumanError(), hint,
|
|
|
|
|
usefulErr.AdditionalHelp(), usefulErr.Error())
|
|
|
|
|
} else {
|
|
|
|
|
printMinimalError(usefulErr.Code(), usefulErr.HumanError(), hint)
|
|
|
|
|
}
|
2025-08-21 18:26:05 +05:30
|
|
|
|
2026-05-19 14:40:54 +05:30
|
|
|
os.Exit(code)
|
2025-08-21 18:26:05 +05:30
|
|
|
}
|
2026-01-17 14:05:01 +05:30
|
|
|
|
2026-05-29 20:19:53 +05:30
|
|
|
// Error output goes to stderr so the wrapped package manager's stdout passes
|
|
|
|
|
// through clean (e.g. `pmg npm view --json` stays parseable).
|
2026-01-17 14:05:01 +05:30
|
|
|
func printMinimalError(code, message, hint string) {
|
2026-05-29 20:19:53 +05:30
|
|
|
fmt.Fprintf(os.Stderr, "%s %s\n", Colors.ErrorCode(" %s ", code), Colors.Red(message))
|
2026-01-17 14:05:01 +05:30
|
|
|
|
|
|
|
|
if hint != "" && hint != "No additional help is available for this error." {
|
2026-05-29 20:19:53 +05:30
|
|
|
fmt.Fprintf(os.Stderr, " %s %s\n", Colors.Dim("→"), Colors.Dim(hint))
|
2026-01-17 14:05:01 +05:30
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func printVerboseError(code, message, hint, additionalHelp, originalError string) {
|
2026-05-29 20:19:53 +05:30
|
|
|
fmt.Fprintf(os.Stderr, "%s %s\n", Colors.ErrorCode(" %s ", code), Colors.Red(message))
|
2026-01-17 14:05:01 +05:30
|
|
|
|
|
|
|
|
if hint != "" && hint != "No additional help is available for this error." {
|
2026-05-29 20:19:53 +05:30
|
|
|
fmt.Fprintf(os.Stderr, " %s %s\n", Colors.Dim("→"), Colors.Dim(hint))
|
2026-01-17 14:05:01 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if additionalHelp != "" && additionalHelp != "No additional help is available for this error." {
|
2026-05-29 20:19:53 +05:30
|
|
|
fmt.Fprintf(os.Stderr, " %s %s\n", Colors.Dim("→"), Colors.Dim(additionalHelp))
|
2026-01-17 14:05:01 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if originalError != "" && originalError != message {
|
2026-05-29 20:19:53 +05:30
|
|
|
fmt.Fprintf(os.Stderr, " %s %s\n", Colors.Dim("┄"), Colors.Dim(originalError))
|
2026-01-17 14:05:01 +05:30
|
|
|
}
|
|
|
|
|
}
|