Skip to content

Commit

Permalink
feat: report bug to sentry (#4328)
Browse files Browse the repository at this point in the history
  • Loading branch information
julienrbrt committed Sep 13, 2024
1 parent bf87ef0 commit 0adabfd
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 10 deletions.
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
- [#4290](https://github.com/ignite/cli/pull/4290) Remove ignite ics logic from ignite cli (this functionality will be in the `consumer` app)
- [#4295](https://github.com/ignite/cli/pull/4295) Stop scaffolding `pulsar` files
- [#4317](https://github.com/ignite/cli/pull/4317) Remove xchisel dependency
- [#4328](https://github.com/ignite/cli/pull/4328) Send ignite bug report to sentry. Opt out the same way as for usage analytics

### Fixes

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ require (
github.com/cosmos/gogoproto v1.7.0
github.com/emicklei/proto v1.12.2
github.com/emicklei/proto-contrib v0.15.0
github.com/getsentry/sentry-go v0.27.0
github.com/go-delve/delve v1.21.0
github.com/go-git/go-git/v5 v5.12.0
github.com/go-openapi/analysis v0.23.0
Expand Down Expand Up @@ -214,7 +215,6 @@ require (
github.com/firefart/nonamedreturns v1.0.5 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/fzipp/gocyclo v0.6.0 // indirect
github.com/getsentry/sentry-go v0.27.0 // indirect
github.com/ghostiam/protogetter v0.3.6 // indirect
github.com/go-chi/chi/v5 v5.0.12 // indirect
github.com/go-critic/go-critic v0.11.4 // indirect
Expand Down
7 changes: 5 additions & 2 deletions ignite/cmd/ignite/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,13 @@ import (
"github.com/ignite/cli/v29/ignite/pkg/xstrings"
)

const exitCodeOK, exitCodeError = 0, 1

func main() {
os.Exit(run())
}

func run() int {
const exitCodeOK, exitCodeError = 0, 1
ctx := clictx.From(context.Background())
cmd, cleanUp, err := ignitecmd.New(ctx)
if err != nil {
Expand All @@ -41,6 +42,7 @@ func run() int {
}
var wg sync.WaitGroup
analytics.SendMetric(&wg, subCmd)
analytics.EnableSentry(&wg, ctx)

err = cmd.ExecuteContext(ctx)
if err != nil {
Expand Down Expand Up @@ -77,7 +79,8 @@ func run() int {
return exitCodeError
}

wg.Wait() // waits for all metrics to be sent
// waits for analytics to finish
wg.Wait()

return exitCodeOK
}
Expand Down
18 changes: 18 additions & 0 deletions ignite/internal/analytics/analytics.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/ignite/cli/v29/ignite/pkg/gitpod"
"github.com/ignite/cli/v29/ignite/pkg/matomo"
"github.com/ignite/cli/v29/ignite/pkg/randstr"
"github.com/ignite/cli/v29/ignite/pkg/sentry"
"github.com/ignite/cli/v29/ignite/version"
)

Expand Down Expand Up @@ -99,6 +100,23 @@ func SendMetric(wg *sync.WaitGroup, cmd *cobra.Command) {
}()
}

// EnableSentry enable errors reporting to Sentry.
func EnableSentry(wg *sync.WaitGroup, ctx context.Context) {

Check failure on line 104 in ignite/internal/analytics/analytics.go

View workflow job for this annotation

GitHub Actions / Lint Go code

context-as-argument: context.Context should be the first parameter of a function (revive)
dntInfo, err := checkDNT()
if err != nil || dntInfo.DoNotTrack {
return
}

closeSentry, err := sentry.InitSentry(ctx)
wg.Add(1)
go func() {
defer wg.Done()
if err == nil {
defer closeSentry()
}
}()
}

// checkDNT check if the user allow to track data or if the DO_NOT_TRACK
// env var is set https://consoledonottrack.com/
func checkDNT() (anonIdentity, error) {
Expand Down
33 changes: 26 additions & 7 deletions ignite/pkg/errors/xerrors.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,45 @@ package errors

import (
"github.com/cockroachdb/errors"
"github.com/getsentry/sentry-go"
)

// New creates an error with a simple error message.
// A stack trace is retained.
func New(msg string) error { return errors.New(msg) }
func New(msg string) error {
err := errors.New(msg)
sentry.CaptureException(err)
return err
}

// Errorf aliases Newf().
func Errorf(format string, args ...interface{}) error { return errors.Errorf(format, args...) }
func Errorf(format string, args ...interface{}) error {
err := errors.Errorf(format, args...)
sentry.CaptureException(err)
return err
}

// WithStack annotates err with a stack trace at the point WithStack was called.
func WithStack(err error) error {
errWithStack := errors.WithStack(err)
sentry.CaptureException(errWithStack)
return errWithStack
}

// Wrap wraps an error with a message prefix. A stack trace is retained.
func Wrap(err error, msg string) error { return errors.Wrap(err, msg) }
func Wrap(err error, msg string) error {
errWrap := errors.Wrap(err, msg)
sentry.CaptureException(errWrap)
return errWrap
}

// Wrapf wraps an error with a formatted message prefix. A stack
// trace is also retained. If the format is empty, no prefix is added,
// but the extra arguments are still processed for reportable strings.
func Wrapf(err error, format string, args ...interface{}) error {
return errors.Wrapf(err, format, args...)
errWrap := errors.Wrapf(err, format, args...)
sentry.CaptureException(errWrap)
return errWrap
}

// Unwrap accesses the direct cause of the error if any, otherwise
Expand All @@ -52,6 +74,3 @@ func Is(err, reference error) bool { return errors.Is(err, reference) }
// As(interface{}) bool such that As(target) returns true. As will panic if target
// is not a non-nil pointer to a type which implements error or is of interface type.
func As(err error, target interface{}) bool { return errors.As(err, target) }

// WithStack annotates err with a stack trace at the point WithStack was called.
func WithStack(err error) error { return errors.WithStack(err) }
48 changes: 48 additions & 0 deletions ignite/pkg/sentry/sentry.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package sentry

import (
"context"
"fmt"
"strings"
"time"

"github.com/getsentry/sentry-go"

"github.com/ignite/cli/v29/ignite/pkg/errors"
"github.com/ignite/cli/v29/ignite/version"
)

const IgniteDNS = "https://bugs.ignite.com"

func InitSentry(ctx context.Context) (deferMe func(), err error) {
sentrySyncTransport := sentry.NewHTTPSyncTransport()
sentrySyncTransport.Timeout = time.Second * 3

igniteInfo, err := version.GetInfo(ctx)
if err != nil {
return nil, errors.Errorf("failed to init sentry: %w", err)
}

if err := sentry.Init(sentry.ClientOptions{
Dsn: IgniteDNS,
Transport: sentrySyncTransport,
Environment: getEnvironment(igniteInfo.CLIVersion),
Release: fmt.Sprintf("ignite@%s", igniteInfo.CLIVersion),
SampleRate: 1.0, // get all events
}); err != nil {
return nil, errors.Errorf("failed to init sentry: %w", err)
}

return func() {
sentry.Recover()
sentry.Flush(time.Second * 2)
}, nil
}

func getEnvironment(igniteVersion string) string {
if strings.Contains(igniteVersion, "dev") {
return "development"
}

return "production"
}

0 comments on commit 0adabfd

Please sign in to comment.