Skip to content

Commit 61c413c

Browse files
authored
v2.1.0 (#18)
1 parent 22df4db commit 61c413c

File tree

8 files changed

+332
-181
lines changed

8 files changed

+332
-181
lines changed

CHANGELOG.md

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,31 @@ All notable changes to this project are documented in this file.
33
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
44

55
- **Major**: backwards incompatible package updates
6-
- **Minor**: feature additions
6+
- **Minor**: feature additions, removal of deprecated features
77
- **Patch**: bug fixes, backward compatible model and function changes, etc.
88

9-
# v2.0.0 - 2020-05-01
9+
# v2.1.0 - 2020-05-30
10+
#### Added
11+
* Additional documentation
12+
* Pre-generics implementation of `As`, returns the error instance when found
13+
14+
#### Changed
15+
* Upgrade to `bdlm/std` v2.1.0
16+
* Cleaner type checking in `Is` methods
17+
18+
#### Removed
19+
* deprecated `Has` methods, use `Is` instead
20+
21+
# v2.0.1 - 2020-05-01
22+
#### Added
23+
* n/a
24+
1025
#### Changed
1126
* Refactoring to better implement the `std/errors.Error` interface
1227

28+
#### Removed
29+
* n/a
30+
1331
# v2.0.0 - 2020-05-01
1432
`v2.0.0` is the production release of the `v0.2.0` development branch.
1533

@@ -33,6 +51,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
3351
#### Changed
3452
* Minor formatting updates and cleanup
3553

54+
#### Removed
55+
* n/a
56+
3657

3758
# v0.2.0 - 2019-07-18
3859
This release is a full rewrite of the `errors` package. See the [README](README.md) for further details.
@@ -62,20 +83,41 @@ This release is a full rewrite of the `errors` package. See the [README](README.
6283

6384

6485
# v0.1.3 - 2018-10-02
86+
#### Added
87+
* n/a
88+
6589
#### Changed
6690
* Fixes a message formatting error
6791

92+
#### Removed
93+
* n/a
6894

6995
# v0.1.2 - 2018-09-09
96+
#### Added
97+
* n/a
98+
7099
#### Changed
71100
* Fixes issues with concurrent writes
72101

102+
#### Removed
103+
* n/a
73104

74105
# v0.1.1 - 2018-08-22
75106
#### Added
76107
* Implemented a `Trace` method
77108

109+
#### Changed
110+
* n/a
111+
112+
#### Removed
113+
* n/a
78114

79115
# v0.1.0 - 2018-06-23
80116
#### Added
81117
* Initial release
118+
119+
#### Changed
120+
* n/a
121+
122+
#### Removed
123+
* n/a

README.md

Lines changed: 63 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<a href="https://github.com/mkenney/software-guides/blob/master/STABILITY-BADGES.md#mature"><img src="https://img.shields.io/badge/stability-mature-008000.svg" alt="Mature"></a> This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). This package is considered mature, you should expect package stability in <strong>Minor</strong> and <strong>Patch</strong> version releases
44

55
- **Major**: backwards incompatible package updates
6-
- **Minor**: feature additions
6+
- **Minor**: feature additions, removal of deprecated features
77
- **Patch**: bug fixes, backward compatible model and function changes, etc.
88

99
**[CHANGELOG](CHANGELOG.md)**<br>
@@ -36,7 +36,7 @@ go get github.com/bdlm/errors/v2
3636

3737
## Quick start
3838

39-
See the [documentation](https://pkg.go.dev/github.com/bdlm/errors#pkg-examples) for more examples. All exported methods work with any `error` type as well as `nil` values.
39+
See the [documentation](https://pkg.go.dev/github.com/bdlm/errors#pkg-examples) for more examples. All package methods work with any `error` type as well as `nil` values, and error instances implement the [`Unwrap`](https://go.googlesource.com/proposal/+/master/design/go2draft-error-inspection.md), [`Is`](https://go.googlesource.com/proposal/+/master/design/go2draft-error-inspection.md), [`Marshaler`](https://golang.org/pkg/encoding/json/#Marshaler), [`Unmarshaler`](https://golang.org/pkg/encoding/json/#Unmarshaler), and [`Formatter`](https://golang.org/pkg/fmt/#Formatter) interfaces as well as the [`github.com/bdlm/std/errors`](https://github.com/bdlm/std/tree/master/errors) interfaces.
4040

4141
#### Create an error
4242
```go
@@ -75,23 +75,12 @@ if prevErr := errors.Unwrap(err); nil != prevErr {
7575
}
7676
```
7777

78-
#### Test for a specific error type
79-
```go
80-
var MyError = errors.New("My error")
81-
func main() {
82-
err := doWork()
83-
if errors.Is(err, MyError) {
84-
...
85-
}
86-
}
87-
```
88-
8978
#### Test to see if a specific error type exists anywhere in an error stack
9079
```go
9180
var MyError = errors.New("My error")
9281
func main() {
9382
err := doWork()
94-
if errors.Has(err, MyError) {
83+
if errors.Is(err, MyError) {
9584
...
9685
}
9786
}
@@ -106,54 +95,69 @@ for nil != err {
10695
}
10796
```
10897

109-
#
110-
111-
See the [documentation](https://godoc.org/github.com/bdlm/errors#pkg-examples) for more examples.
112-
113-
114-
## The `Error` interface
98+
#### Formatting verbs
99+
`errors` implements the `%s` and `%v` [`fmt.Formatter`](https://golang.org/pkg/fmt/#hdr-Printing) formatting verbs and several modifier flags:
115100

116-
The exported package methods return `github.com/bdlm/std/v2/errors` interfaces that expose metadata and troubleshooting information:
101+
##### Verbs
102+
* `%s` - Returns the error string of the last error added.
103+
* `%v` - Alias for `%s`
117104

118-
```go
119-
// Error defines a robust error stack interface.
120-
type Error interface {
121-
// Caller returns the associated Caller instance.
122-
Caller() Caller
123-
124-
// Error implements error.
125-
Error() string
126-
127-
// Has tests to see if the test error exists anywhere in the error
128-
// stack.
129-
Has(test error) bool
105+
##### Flags
106+
* `#` - JSON formatted output, useful for logging
107+
* `-` - Output caller details, useful for troubleshooting
108+
* `+` - Output full error stack details, useful for debugging
109+
* ` ` - (space) Add whitespace formatting for readability, useful for development
130110

131-
// Is tests to see if the test error matches most recent error in the
132-
// stack.
133-
Is(test error) bool
134-
135-
// Unwrap returns the next error, if any.
136-
Unwrap() Error
111+
##### Examples
112+
`fmt.Printf("%s", err)`
113+
```
114+
An error occurred
115+
```
116+
`fmt.Printf("%v", err)`
117+
```
118+
An error occurred
119+
```
120+
`fmt.Printf("%-v", err)`
121+
```
122+
#0 stack_test.go:40 (github.com/bdlm/error_test.TestErrors) - An error occurred
123+
```
124+
`fmt.Printf("%+v", err)`
125+
```
126+
#0 stack_test.go:40 (github.com/bdlm/error_test.TestErrors) - An error occurred #1 stack_test.go:39 (github.com/bdlm/error_test.TestErrors) - An error occurred
127+
```
128+
`fmt.Printf("%#v", err)`
129+
```json
130+
{"error":"An error occurred"}
131+
```
132+
`fmt.Printf("%#-v", err)`
133+
```json
134+
{"caller":"#0 stack_test.go:40 (github.com/bdlm/error_test.TestErrors)","error":"An error occurred"}
135+
```
136+
`fmt.Printf("%#+v", err)`
137+
```json
138+
[{"caller":"#0 stack_test.go:40 (github.com/bdlm/error_test.TestErrors)","error":"An error occurred"},{"caller":"#1 stack_test.go:39 (github.com/bdlm/error_test.TestErrors)","error":"An error occurred"}]
139+
```
140+
`fmt.Printf("% #-v", err)`
141+
```json
142+
{
143+
"caller": "#0 stack_test.go:40 (github.com/bdlm/error_test.TestErrors)",
144+
"error": "An error occurred"
137145
}
146+
```
147+
`fmt.Printf("% #+v", err)`
148+
```json
149+
[
150+
{
151+
"caller": "#0 stack_test.go:40 (github.com/bdlm/error_test.TestErrors)",
152+
"error": "An error occurred"
153+
},
154+
{
155+
"caller": "#1 stack_test.go:39 (github.com/bdlm/error_test.TestErrors)",
156+
"error": "An error occurred"
157+
}
158+
]
159+
```
138160

139-
// Caller defines an interface to runtime caller results.
140-
type Caller interface {
141-
// File returns the file in which the call occurred.
142-
File() string
143-
144-
// Func returns the name of the function in which the call occurred.
145-
Func() string
146-
147-
// Line returns the line number in the file in which the call occurred.
148-
Line() int
149-
150-
// Pc returns the program counter.
151-
Pc() uintptr
152-
153-
// Trace returns the call stack.
154-
Trace() Trace
155-
}
161+
#
156162

157-
// Trace defines an error trace.
158-
type Trace []Caller
159-
```
163+
See the [documentation](https://godoc.org/github.com/bdlm/errors#pkg-examples) for more examples.

caller.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import (
55
"runtime"
66
"strings"
77

8-
std_err "github.com/bdlm/std/v2/errors"
8+
std_caller "github.com/bdlm/std/v2/caller"
99
)
1010

1111
// caller is a github.com/bdlm/std.Caller interface implementation and holds
@@ -15,12 +15,12 @@ type caller struct {
1515
line int
1616
ok bool
1717
pc uintptr
18-
trace std_err.Trace
18+
trace std_caller.Trace
1919
}
2020

2121
// NewCaller returns a new Caller containing data for the current call stack.
22-
func NewCaller() std_err.Caller {
23-
trace := std_err.Trace{}
22+
func NewCaller() std_caller.Caller {
23+
trace := std_caller.Trace{}
2424
clr := &caller{}
2525
a := 0
2626
for {
@@ -75,6 +75,6 @@ func (caller *caller) String() string {
7575
}
7676

7777
// Trace implements Caller.
78-
func (caller *caller) Trace() std_err.Trace {
78+
func (caller *caller) Trace() std_caller.Trace {
7979
return caller.trace
8080
}

error.go

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,77 @@
11
package errors
22

33
import (
4-
std_err "github.com/bdlm/std/v2/errors"
4+
"reflect"
5+
6+
std_caller "github.com/bdlm/std/v2/caller"
7+
std_error "github.com/bdlm/std/v2/errors"
58
)
69

710
// E is a github.com/bdlm/std.Error interface implementation and simply wraps
811
// the exported package methods as a convenience.
912
type E struct {
10-
caller std_err.Caller
13+
caller std_caller.Caller
1114
err error
1215
prev error
1316
}
1417

15-
// Caller implements std.Error.
16-
func (e *E) Caller() std_err.Caller {
18+
// Caller implements std_error.Caller.
19+
func (e *E) Caller() std_caller.Caller {
1720
if nil == e {
1821
return nil
1922
}
2023
return e.caller
2124
}
2225

23-
// Error implements std.Error.
26+
// Error implements std_error.Error.
2427
func (e *E) Error() string {
2528
return e.err.Error()
2629
}
2730

28-
// Has implements std.Error.
29-
func (e *E) Has(test error) bool {
30-
if e.Is(test) {
31-
return true
32-
}
33-
if prev := e.Unwrap(); nil != prev {
34-
return prev.Has(test)
35-
}
36-
return false
37-
}
38-
39-
// Is implements std.Error.
31+
// Is implements std_error.Error.
4032
func (e *E) Is(test error) bool {
4133
if nil == test {
4234
return false
4335
}
44-
if e.err == test && e.Error() == test.Error() {
36+
37+
isComparable := reflect.TypeOf(e).Comparable() && reflect.TypeOf(test).Comparable()
38+
if isComparable && e == test {
4539
return true
4640
}
47-
if std, ok := test.(std_err.Error); ok {
48-
return func(e1, e2 std_err.Error) bool {
49-
return e1 == e2 && e1.Error() == e2.Error()
50-
}(e, std)
41+
isComparable = reflect.TypeOf(e.err).Comparable() && reflect.TypeOf(test).Comparable()
42+
if isComparable && e.err == test {
43+
return true
5144
}
45+
46+
if testE, ok := test.(*E); ok {
47+
isComparable = reflect.TypeOf(e).Comparable() && reflect.TypeOf(testE).Comparable()
48+
if isComparable && e == testE {
49+
return true
50+
}
51+
isComparable = reflect.TypeOf(e.err).Comparable() && reflect.TypeOf(testE.err).Comparable()
52+
if isComparable && e.err == testE.err {
53+
return true
54+
}
55+
}
56+
57+
if err := e.Unwrap(); nil != err {
58+
if err, ok := err.(interface{ Is(error) bool }); ok {
59+
return err.Is(test)
60+
}
61+
}
62+
5263
return false
5364
}
5465

55-
// Unwrap implements std.Error.
56-
func (e *E) Unwrap() std_err.Error {
66+
// Unwrap implements std_error.Wrapper.
67+
func (e *E) Unwrap() error {
5768
if nil == e {
5869
return nil
5970
}
6071
if nil == e.prev {
6172
return nil
6273
}
63-
if prev, ok := e.prev.(std_err.Error); ok {
74+
if prev, ok := e.prev.(std_error.Error); ok {
6475
return prev
6576
}
6677
return &E{
@@ -73,7 +84,7 @@ func list(e error) []error {
7384
ret := []error{}
7485

7586
if nil != e {
76-
if std, ok := e.(std_err.Error); ok {
87+
if std, ok := e.(std_error.Wrapper); ok {
7788
ret = append(ret, e)
7889
ret = append(ret, list(std.Unwrap())...)
7990
}

0 commit comments

Comments
 (0)