...

Source file src/github.com/goph/emperror/handler/sentryhandler/handler.go

Documentation: github.com/goph/emperror/handler/sentryhandler

     1  package sentryhandler
     2  
     3  import (
     4  	"github.com/getsentry/raven-go"
     5  	"github.com/pkg/errors"
     6  
     7  	"github.com/goph/emperror"
     8  	"github.com/goph/emperror/httperr"
     9  	"github.com/goph/emperror/internal/keyvals"
    10  )
    11  
    12  // Handler is responsible for sending errors to Sentry.
    13  type Handler struct {
    14  	client *raven.Client
    15  
    16  	sendSynchronously bool
    17  }
    18  
    19  // New creates a new handler.
    20  func New(dsn string) (*Handler, error) {
    21  	client, err := raven.New(dsn)
    22  	if err != nil {
    23  		return nil, errors.Wrap(err, "failed to create raven client")
    24  	}
    25  
    26  	return NewFromClient(client), nil
    27  }
    28  
    29  // NewSync creates a new handler that sends errors synchronously.
    30  func NewSync(dsn string) (*Handler, error) {
    31  	handler, err := New(dsn)
    32  	if err != nil {
    33  		return nil, err
    34  	}
    35  
    36  	handler.sendSynchronously = true
    37  
    38  	return handler, nil
    39  }
    40  
    41  // NewFromClient creates a new handler from a client instance.
    42  func NewFromClient(client *raven.Client) *Handler {
    43  	return &Handler{
    44  		client: client,
    45  	}
    46  }
    47  
    48  // NewSyncFromClient creates a new handler from a client instance that sends errors synchronously.
    49  func NewSyncFromClient(client *raven.Client) *Handler {
    50  	handler := NewFromClient(client)
    51  
    52  	handler.sendSynchronously = true
    53  
    54  	return handler
    55  }
    56  
    57  // Handle sends the error to Rollbar.
    58  func (h *Handler) Handle(err error) {
    59  	var interfaces []raven.Interface
    60  
    61  	// Get HTTP request (if any)
    62  	if req, ok := httperr.HTTPRequest(err); ok {
    63  		interfaces = append(interfaces, raven.NewHttp(req))
    64  	}
    65  
    66  	packet := raven.NewPacketWithExtra(
    67  		err.Error(),
    68  		keyvals.ToMap(emperror.Context(err)),
    69  		append(
    70  			interfaces,
    71  			raven.NewException(
    72  				err,
    73  				raven.GetOrNewStacktrace(emperror.ExposeStackTrace(err), 1, 3, h.client.IncludePaths()),
    74  			),
    75  		)...,
    76  	)
    77  
    78  	eventID, ch := h.client.Capture(packet, nil)
    79  
    80  	if h.sendSynchronously && eventID != "" {
    81  		<-ch
    82  	}
    83  }
    84  
    85  // Close closes the underlying notifier and waits for asynchronous reports to finish.
    86  func (h *Handler) Close() error {
    87  	h.client.Close()
    88  	h.client.Wait()
    89  
    90  	return nil
    91  }
    92  

View as plain text