mirror of
https://github.com/absmach/supermq.git
synced 2026-06-23 06:30:22 +00:00
22ecbc24ee
Improve error handling and SDK error testing. The code now includes signal handling, error wrapping, checking for contained errors, and testing HTTP error responses. Additionally, assertions have been added to ensure the expected behavior is met. Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>
129 lines
2.2 KiB
Go
129 lines
2.2 KiB
Go
// Copyright (c) Abstract Machines
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package errors
|
|
|
|
import (
|
|
"encoding/json"
|
|
)
|
|
|
|
// Error specifies an API that must be fullfiled by error type.
|
|
type Error interface {
|
|
// Error implements the error interface.
|
|
Error() string
|
|
|
|
// Msg returns error message.
|
|
Msg() string
|
|
|
|
// Err returns wrapped error.
|
|
Err() Error
|
|
|
|
// MarshalJSON returns a marshaled error.
|
|
MarshalJSON() ([]byte, error)
|
|
}
|
|
|
|
var _ Error = (*customError)(nil)
|
|
|
|
// customError represents a Magistrala error.
|
|
type customError struct {
|
|
msg string
|
|
err Error
|
|
}
|
|
|
|
// New returns an Error that formats as the given text.
|
|
func New(text string) Error {
|
|
return &customError{
|
|
msg: text,
|
|
err: nil,
|
|
}
|
|
}
|
|
|
|
func (ce *customError) Error() string {
|
|
if ce == nil {
|
|
return ""
|
|
}
|
|
if ce.err == nil {
|
|
return ce.msg
|
|
}
|
|
return ce.msg + " : " + ce.err.Error()
|
|
}
|
|
|
|
func (ce *customError) Msg() string {
|
|
return ce.msg
|
|
}
|
|
|
|
func (ce *customError) Err() Error {
|
|
return ce.err
|
|
}
|
|
|
|
func (ce *customError) MarshalJSON() ([]byte, error) {
|
|
var val string
|
|
if e := ce.Err(); e != nil {
|
|
val = e.Msg()
|
|
}
|
|
return json.Marshal(&struct {
|
|
Err string `json:"error"`
|
|
Msg string `json:"message"`
|
|
}{
|
|
Err: val,
|
|
Msg: ce.Msg(),
|
|
})
|
|
}
|
|
|
|
// Contains inspects if e2 error is contained in any layer of e1 error.
|
|
func Contains(e1, e2 error) bool {
|
|
if e1 == nil || e2 == nil {
|
|
return e2 == e1
|
|
}
|
|
ce, ok := e1.(Error)
|
|
if ok {
|
|
if ce.Msg() == e2.Error() {
|
|
return true
|
|
}
|
|
return Contains(ce.Err(), e2)
|
|
}
|
|
return e1.Error() == e2.Error()
|
|
}
|
|
|
|
// Wrap returns an Error that wrap err with wrapper.
|
|
func Wrap(wrapper, err error) error {
|
|
if wrapper == nil || err == nil {
|
|
return wrapper
|
|
}
|
|
if w, ok := wrapper.(Error); ok {
|
|
return &customError{
|
|
msg: w.Msg(),
|
|
err: cast(err),
|
|
}
|
|
}
|
|
return &customError{
|
|
msg: wrapper.Error(),
|
|
err: cast(err),
|
|
}
|
|
}
|
|
|
|
// Unwrap returns the wrapper and the error by separating the Wrapper from the error.
|
|
func Unwrap(err error) (error, error) {
|
|
if ce, ok := err.(Error); ok {
|
|
if ce.Err() == nil {
|
|
return nil, New(ce.Msg())
|
|
}
|
|
return New(ce.Msg()), ce.Err()
|
|
}
|
|
|
|
return nil, err
|
|
}
|
|
|
|
func cast(err error) Error {
|
|
if err == nil {
|
|
return nil
|
|
}
|
|
if e, ok := err.(Error); ok {
|
|
return e
|
|
}
|
|
return &customError{
|
|
msg: err.Error(),
|
|
err: nil,
|
|
}
|
|
}
|