Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gitpod-io
GitHub Repository: gitpod-io/gitpod
Path: blob/main/components/local-app/pkg/prettyprint/errors.go
2500 views
1
// Copyright (c) 2023 Gitpod GmbH. All rights reserved.
2
// Licensed under the GNU Affero General Public License (AGPL).
3
// See License.AGPL.txt in the project root for license information.
4
5
package prettyprint
6
7
import (
8
"errors"
9
"fmt"
10
"io"
11
"runtime"
12
"strings"
13
14
"github.com/gookit/color"
15
)
16
17
var (
18
styleError = color.New(color.FgRed, color.Bold)
19
stylePossibleResolutions = color.New(color.FgGreen, color.Bold)
20
styleApology = color.New(color.FgYellow, color.Bold)
21
)
22
23
// PrintError prints an error to the given writer.
24
func PrintError(out io.Writer, command string, err error) {
25
fmt.Fprintf(out, "%s%s\n\n", styleError.Sprint("Error: "), err.Error())
26
27
var (
28
resolutions []string
29
apology bool
30
)
31
for err != nil {
32
if r, ok := err.(*ErrResolution); ok {
33
resolutions = append(resolutions, r.Resolutions...)
34
}
35
if _, ok := err.(*ErrSystemException); ok {
36
apology = true
37
}
38
39
err = errors.Unwrap(err)
40
}
41
if len(resolutions) > 0 {
42
fmt.Fprint(out, stylePossibleResolutions.Sprint("Possible resolutions:\n"))
43
for _, r := range resolutions {
44
r = strings.ReplaceAll(r, "{gitpod}", command)
45
fmt.Fprintf(out, " - %s\n", r)
46
}
47
fmt.Fprintln(out)
48
}
49
if apology {
50
fmt.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"))
51
}
52
}
53
54
// AddResolution adds a resolution to an error. Resolutions are hints that tell the user how to resolve the error.
55
func AddResolution(err error, resolution ...string) *ErrResolution {
56
return &ErrResolution{
57
Err: err,
58
Resolutions: resolution,
59
}
60
}
61
62
type ErrResolution struct {
63
Err error
64
Resolutions []string
65
}
66
67
func (e *ErrResolution) Error() string {
68
return e.Err.Error()
69
}
70
71
func (e *ErrResolution) Unwrap() error {
72
return e.Err
73
}
74
75
func MarkExceptional(err error) *ErrSystemException {
76
context := "unknown"
77
if _, file, no, ok := runtime.Caller(1); ok {
78
context = fmt.Sprintf("%s:%d", file, no)
79
}
80
return &ErrSystemException{
81
Context: context,
82
Err: err,
83
}
84
}
85
86
type ErrSystemException struct {
87
Context string
88
Err error
89
}
90
91
func (e ErrSystemException) Error() string {
92
return e.Err.Error()
93
}
94
95
func (e ErrSystemException) Unwrap() error {
96
return e.Err
97
}
98
99