Skip to content

Commit

Permalink
Allow for errors.As() to see the underlying AMQP error (#329)
Browse files Browse the repository at this point in the history
You can now do errors.As() and grab the amqp.Error{} out of Link/Session/ConnErrors.
  • Loading branch information
richardpark-msft authored Aug 20, 2024
1 parent 1003610 commit 58e8fd8
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 0 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Release History

## 1.1.0 (2024-08-20)

### Features Added

* ConnError, SessionError and LinkError now work with errors.As(), making it easier to write generalized error handling code that wants to deal with *amqp.Error's.

## 1.0.5 (2024-03-04)

### Bugs Fixed
Expand Down
27 changes: 27 additions & 0 deletions errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,15 @@ func (e *LinkError) Error() string {
return e.inner.Error()
}

// Unwrap returns the RemoteErr, if any.
func (e *LinkError) Unwrap() error {
if e.RemoteErr == nil {
return nil
}

return e.RemoteErr
}

// ConnError is returned by methods on Conn and propagated to Session and Senders/Receivers
// when the connection has been closed.
type ConnError struct {
Expand All @@ -84,6 +93,15 @@ func (e *ConnError) Error() string {
return e.inner.Error()
}

// Unwrap returns the RemoteErr, if any.
func (e *ConnError) Unwrap() error {
if e.RemoteErr == nil {
return nil
}

return e.RemoteErr
}

// SessionError is returned by methods on Session and propagated to Senders/Receivers
// when the session has been closed.
type SessionError struct {
Expand All @@ -102,3 +120,12 @@ func (e *SessionError) Error() string {
}
return e.inner.Error()
}

// Unwrap returns the RemoteErr, if any.
func (e *SessionError) Unwrap() error {
if e.RemoteErr == nil {
return nil
}

return e.RemoteErr
}
44 changes: 44 additions & 0 deletions errors_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package amqp_test

import (
"errors"
"testing"

amqp "github.com/Azure/go-amqp"
"github.com/stretchr/testify/require"
)

func TestErrorUnwrap(t *testing.T) {
// In the majority of common use cases, the LinkError, ConnError and SessionError will contain an amqp.Error.
// It's simpler, for callers, if they can simply check errors.As(&amqp.Error) so they can write general error
// handling, rather than having to check the envelope type each time.
t.Run("LinkError", func(t *testing.T) {
var amqpErr *amqp.Error

le := &amqp.LinkError{}
require.False(t, errors.As(le, &amqpErr))

le.RemoteErr = &amqp.Error{Condition: amqp.ErrCondConnectionForced}
require.ErrorAs(t, le, &amqpErr)
})

t.Run("ConnError", func(t *testing.T) {
var amqpErr *amqp.Error

ce := &amqp.ConnError{}
require.False(t, errors.As(ce, &amqpErr))

ce.RemoteErr = &amqp.Error{Condition: amqp.ErrCondConnectionForced}
require.ErrorAs(t, ce, &amqpErr)
})

t.Run("SessionError", func(t *testing.T) {
var amqpErr *amqp.Error

se := &amqp.ConnError{}
require.False(t, errors.As(se, &amqpErr))

se.RemoteErr = &amqp.Error{Condition: amqp.ErrCondConnectionForced}
require.ErrorAs(t, se, &amqpErr)
})
}

0 comments on commit 58e8fd8

Please sign in to comment.