Skip to content
This repository has been archived by the owner on Aug 30, 2023. It is now read-only.

Commit

Permalink
Add methods that return error when capturing
Browse files Browse the repository at this point in the history
The client's capture method returns an error channel that according to
the docs is intended to be used for checking if a packet was sent
successfully whenever that is important.

The `...AndWait` methods use this channel, but only to wait. They do
not capture the possible error coming from that channel.

The changes in this commit suggest to use the error and return it, so
that a user may check whether a packet was sent successfully using new top
level methods, instead of having to write their own.

The newly introduced methods follow the naming scheme
`Capture$SOMETHINGAndConfirm`, where the returned error is considered
confirmation.

Work on #84
  • Loading branch information
Valentin Krasontovitsch committed Nov 20, 2017
1 parent 4b229b2 commit c96349a
Showing 1 changed file with 89 additions and 0 deletions.
89 changes: 89 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -654,6 +654,30 @@ func CaptureMessageAndWait(message string, tags map[string]string, interfaces ..
return DefaultClient.CaptureMessageAndWait(message, tags, interfaces...)
}

// CaptureMessageAndConfirm is identical to CaptureMessage except it blocks and
// waits for the message to be sent and returns an error.
func (client *Client) CaptureMessageAndConfirm(message string, tags map[string]string, interfaces ...Interface) (error, string) {
if client == nil {
return ErrClientNotConfigured, ""
}

if client.shouldExcludeErr(message) {
return nil, ""
}

packet := NewPacket(message, append(append(interfaces, client.context.interfaces()...), &Message{message, nil})...)
eventID, ch := client.Capture(packet, tags)
internalError := <-ch

return internalError, eventID
}

// CaptureMessageAndConfirm is identical to CaptureMessage except it blocks and
// waits for the message to be sent and returns an error.
func CaptureMessageAndConfirm(message string, tags map[string]string, interfaces ...Interface) (error, string) {
return DefaultClient.CaptureMessageAndConfirm(message, tags, interfaces...)
}

// CaptureErrors formats and delivers an error to the Sentry server.
// Adds a stacktrace to the packet, excluding the call to this method.
func (client *Client) CaptureError(err error, tags map[string]string, interfaces ...Interface) string {
Expand Down Expand Up @@ -705,6 +729,30 @@ func CaptureErrorAndWait(err error, tags map[string]string, interfaces ...Interf
return DefaultClient.CaptureErrorAndWait(err, tags, interfaces...)
}

// CaptureErrorAndConfirm is identical to CaptureError, except it blocks and
// assures that the event was sent and returns an error
func (client *Client) CaptureErrorAndConfirm(err error, tags map[string]string, interfaces ...Interface) (error, string) {
if client == nil {
return ErrClientNotConfigured, ""
}

if client.shouldExcludeErr(err.Error()) {
return nil, ""
}

packet := NewPacket(err.Error(), append(append(interfaces, client.context.interfaces()...), NewException(err, NewStacktrace(1, 3, client.includePaths)))...)
eventID, ch := client.Capture(packet, tags)
internalError := <-ch

return internalError, eventID
}

// CaptureErrorAndConfirm is identical to CaptureError, except it blocks and
// assures that the event was sent and returns an error
func CaptureErrorAndConfirm(err error, tags map[string]string, interfaces ...Interface) (error, string) {
return DefaultClient.CaptureErrorAndConfirm(err, tags, interfaces...)
}

// CapturePanic calls f and then recovers and reports a panic to the Sentry server if it occurs.
// If an error is captured, both the error and the reported Sentry error ID are returned.
func (client *Client) CapturePanic(f func(), tags map[string]string, interfaces ...Interface) (err interface{}, errorID string) {
Expand Down Expand Up @@ -785,6 +833,47 @@ func CapturePanicAndWait(f func(), tags map[string]string, interfaces ...Interfa
return DefaultClient.CapturePanicAndWait(f, tags, interfaces...)
}

// CapturePanicAndConfirm is identical to CapturePanic, except it blocks and
// assures that the event was sent and returns an error
func (client *Client) CapturePanicAndConfirm(f func(), tags map[string]string, interfaces ...Interface) (internalError error, err interface{}, errorID string) {
// Note: This doesn't need to check for client, because we still want to go through the defer/recover path
// Down the line, Capture will be noop'd, so while this does a _tiny_ bit of overhead constructing the
// *Packet just to be thrown away, this should not be the normal case. Could be refactored to
// be completely noop though if we cared.
defer func() {
var packet *Packet
err = recover()
switch rval := err.(type) {
case nil:
return
case error:
if client.shouldExcludeErr(rval.Error()) {
return
}
packet = NewPacket(rval.Error(), append(append(interfaces, client.context.interfaces()...), NewException(rval, NewStacktrace(2, 3, client.includePaths)))...)
default:
rvalStr := fmt.Sprint(rval)
if client.shouldExcludeErr(rvalStr) {
return
}
packet = NewPacket(rvalStr, append(append(interfaces, client.context.interfaces()...), NewException(errors.New(rvalStr), NewStacktrace(2, 3, client.includePaths)))...)
}

var ch chan error
errorID, ch = client.Capture(packet, tags)
internalError = <-ch
}()

f()
return
}

// CapturePanicAndConfirm is identical to CapturePanic, except it blocks and
// assures that the event was sent and returns an error
func CapturePanicAndConfirm(f func(), tags map[string]string, interfaces ...Interface) (error, interface{}, string) {
return DefaultClient.CapturePanicAndConfirm(f, tags, interfaces...)
}

func (client *Client) Close() {
close(client.queue)
}
Expand Down

0 comments on commit c96349a

Please # to comment.