diff --git a/client.go b/client.go index d996410..c7c88b8 100644 --- a/client.go +++ b/client.go @@ -664,6 +664,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 nil, "" + } + + 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 { @@ -719,6 +743,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 nil, "" + } + + 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) { @@ -758,7 +806,7 @@ func CapturePanic(f func(), tags map[string]string, interfaces ...Interface) (in return DefaultClient.CapturePanic(f, tags, interfaces...) } -// CapturePanicAndWait is identical to CaptureError, except it blocks and assures that the event was sent +// CapturePanicAndWait is identical to CapturePanic, except it blocks and assures that the event was sent func (client *Client) CapturePanicAndWait(f func(), tags map[string]string, interfaces ...Interface) (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 @@ -794,11 +842,52 @@ func (client *Client) CapturePanicAndWait(f func(), tags map[string]string, inte return } -// CapturePanicAndWait is identical to CaptureError, except it blocks and assures that the event was sent +// CapturePanicAndWait is identical to CapturePanic, except it blocks and assures that the event was sent func CapturePanicAndWait(f func(), tags map[string]string, interfaces ...Interface) (interface{}, string) { 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) }