Path: blob/main/components/local-app/pkg/prettyprint/errors.go
2500 views
// Copyright (c) 2023 Gitpod GmbH. All rights reserved.1// Licensed under the GNU Affero General Public License (AGPL).2// See License.AGPL.txt in the project root for license information.34package prettyprint56import (7"errors"8"fmt"9"io"10"runtime"11"strings"1213"github.com/gookit/color"14)1516var (17styleError = color.New(color.FgRed, color.Bold)18stylePossibleResolutions = color.New(color.FgGreen, color.Bold)19styleApology = color.New(color.FgYellow, color.Bold)20)2122// PrintError prints an error to the given writer.23func PrintError(out io.Writer, command string, err error) {24fmt.Fprintf(out, "%s%s\n\n", styleError.Sprint("Error: "), err.Error())2526var (27resolutions []string28apology bool29)30for err != nil {31if r, ok := err.(*ErrResolution); ok {32resolutions = append(resolutions, r.Resolutions...)33}34if _, ok := err.(*ErrSystemException); ok {35apology = true36}3738err = errors.Unwrap(err)39}40if len(resolutions) > 0 {41fmt.Fprint(out, stylePossibleResolutions.Sprint("Possible resolutions:\n"))42for _, r := range resolutions {43r = strings.ReplaceAll(r, "{gitpod}", command)44fmt.Fprintf(out, " - %s\n", r)45}46fmt.Fprintln(out)47}48if apology {49fmt.Fprintf(out, "%sIt looks like the system decided to take a surprise coffee break. We're not saying it's a bug... but it's a bug. While we can't promise moonshots, our team is peeking under the hood.\n\n", styleApology.Sprint("Our apologies 🙇\n"))50}51}5253// AddResolution adds a resolution to an error. Resolutions are hints that tell the user how to resolve the error.54func AddResolution(err error, resolution ...string) *ErrResolution {55return &ErrResolution{56Err: err,57Resolutions: resolution,58}59}6061type ErrResolution struct {62Err error63Resolutions []string64}6566func (e *ErrResolution) Error() string {67return e.Err.Error()68}6970func (e *ErrResolution) Unwrap() error {71return e.Err72}7374func MarkExceptional(err error) *ErrSystemException {75context := "unknown"76if _, file, no, ok := runtime.Caller(1); ok {77context = fmt.Sprintf("%s:%d", file, no)78}79return &ErrSystemException{80Context: context,81Err: err,82}83}8485type ErrSystemException struct {86Context string87Err error88}8990func (e ErrSystemException) Error() string {91return e.Err.Error()92}9394func (e ErrSystemException) Unwrap() error {95return e.Err96}979899