Skip to content

Commit 4a7bc51

Browse files
authored
Merge pull request #20 from lainio/new-bechmark-goid
v0.9.5 flags CLI support, etc
2 parents 8fe8a79 + d28d311 commit 4a7bc51

19 files changed

+429
-85
lines changed

CHANGELOG.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,42 @@
22

33
### Version history
44

5+
##### 0.9.41
6+
- Issue #18: **bug fixed**: noerr-handler had to be the last one of the err2
7+
handlers
8+
9+
##### 0.9.40
10+
- Significant performance boost for: `defer err2.Handle/Catch()`
11+
- **3x faster happy path than the previous version, which is now equal to
12+
simplest `defer` function in the `err`-returning function** . (Please see
13+
the `defer` benchmarks in the `err2_test.go` and run `make bench_reca`)
14+
- the solution caused a change to API, where the core reason is Go's
15+
optimization "bug". (We don't have confirmation yet.)
16+
- Changed API for deferred error handling: `defer err2.Handle/Catch()`
17+
- *Obsolete*:
18+
```go
19+
defer err2.Handle(&err, func() {}) // <- relaying closure to access err val
20+
```
21+
- Current version:
22+
```go
23+
defer err2.Handle(&err, func(err error) error { return err }) // not a closure
24+
```
25+
Because handler function is not relaying closures any more, it opens a new
26+
opportunity to use and build general helper functions: `err2.Noop`, etc.
27+
- Use auto-migration scripts especially for large code-bases. More information
28+
can be found in the `scripts/` directory's [readme file](./scripts/README.md).
29+
- Added a new (*experimental*) API:
30+
```go
31+
defer err2.Handle(&err, func(noerr bool) {
32+
assert.That(noerr) // noerr is always true!!
33+
doSomething()
34+
})
35+
```
36+
This is experimental because we aren't sure if this is something we want to
37+
have in the `err2` package.
38+
- Bug fixes: `ResultX.Logf()` now works as it should
39+
- More documentation
40+
541
##### 0.9.29
642
- New API for immediate error handling: `try out handle/catch err`
743
`val := try.Out1strconv.Atois.Catch(10)`

Makefile

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ PKGS := $(PKG_ERR2) $(PKG_ASSERT) $(PKG_TRY) $(PKG_DEBUG) $(PKG_HANDLER) $(PKG_S
1212
SRCDIRS := $(shell go list -f '{{.Dir}}' $(PKGS))
1313

1414
GO ?= go
15-
TEST_ARGS ?=
15+
TEST_ARGS ?= -benchmem
16+
# -"gcflags '-N -l'" both optimization & inlining disabled
1617

1718
# GO ?= go1.20rc2
1819

@@ -45,6 +46,9 @@ testv:
4546
test:
4647
$(GO) test $(TEST_ARGS) $(PKGS)
4748

49+
escape_err2:
50+
$(GO) test -c -gcflags=-m=2 $(PKG_ERR2) 2>&1 | ag 'escape'
51+
4852
inline_err2:
4953
$(GO) test -c -gcflags=-m=2 $(PKG_ERR2) 2>&1 | ag 'inlin'
5054

@@ -78,6 +82,9 @@ bench_that:
7882
bench_copy:
7983
$(GO) test $(TEST_ARGS) -bench='Benchmark_CopyBuffer' $(PKG_TRY)
8084

85+
bench_rech:
86+
$(GO) test $(TEST_ARGS) -bench='BenchmarkRecursionWithTryAnd_HeavyPtrPtr_Defer' $(PKG_ERR2)
87+
8188
bench_rece:
8289
$(GO) test $(TEST_ARGS) -bench='BenchmarkRecursionWithTryAnd_Empty_Defer' $(PKG_ERR2)
8390

README.md

Lines changed: 104 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,11 @@ func CopyFile(src, dst string) (err error) {
4444
- [Filters for non-errors like io.EOF](#filters-for-non-errors-like-ioeof)
4545
- [Backwards Compatibility Promise for the API](#backwards-compatibility-promise-for-the-api)
4646
- [Assertion](#assertion)
47+
- [Asserters](#asserters)
4748
- [Assertion Package for Runtime Use](#assertion-package-for-runtime-use)
4849
- [Assertion Package for Unit Testing](#assertion-package-for-unit-testing)
50+
- [Automatic Flags](#automatic-flags)
51+
- [Support for Cobra Flags](#support-for-cobra-flags)
4952
- [Code Snippets](#code-snippets)
5053
- [Background](#background)
5154
- [Learnings by so far](#learnings-by-so-far)
@@ -160,6 +163,10 @@ If no `Tracer` is set no stack tracing is done. This is the default because in
160163
the most cases proper error messages are enough and panics are handled
161164
immediately by a programmer.
162165
166+
> Note. Since v0.9.5 you can set these tracers through Go's standard flag
167+
> package just by adding `flag.Parse()` to your program. See more information
168+
> from [Automatic Flags](#automatic-flags).
169+
163170
[Read the package documentation for more
164171
information](https://pkg.go.dev/github.com/lainio/err2).
165172
@@ -266,6 +273,8 @@ cycle. The default mode is to return an `error` value that includes a formatted
266273
and detailed assertion violation message. A developer gets immediate and proper
267274
feedback, allowing cleanup of the code and APIs before the release.
268275
276+
#### Asserters
277+
269278
The assert package offers a few pre-build *asserters*, which are used to
270279
configure how the assert package deals with assert violations. The line below
271280
exemplifies how the default asserter is set in the package.
@@ -287,6 +296,10 @@ error messages as simple as possible. And by offering option to turn additional
287296
information on, which allows super users and developers get more technical
288297
information when needed.
289298
299+
> Note. Since v0.9.5 you can set these asserters through Go's standard flag
300+
> package just by adding `flag.Parse()` to your program. See more information
301+
> from [Automatic Flags](#automatic-flags).
302+
290303
#### Assertion Package for Runtime Use
291304
292305
Following is example of use of the assert package:
@@ -346,6 +359,90 @@ can be the same or different modules.
346359
execution, we will find it and can even move thru every step in the call
347360
stack.**
348361
362+
## Automatic Flags
363+
364+
When you are using `err2` or `assert` packages, i.e., just importing them, you
365+
have an option to automatically support for err2 configuration flags through
366+
Go's standard `flag` package. See more information about err2 settings from
367+
[Error Stack Tracing](#error-stack-tracing) and [Asserters](#asserters).
368+
369+
Now you can always deploy your applications and services with the simple
370+
end-user friendly error messages and no stack traces, **but you can switch them
371+
on when ever you need**.
372+
373+
Let's say you have build CLI (`your-app`) tool with the support for Go's flag
374+
package, and the app returns an error. Let's assume you're a developer. You can
375+
run it again with:
376+
377+
```
378+
your-app -err2-trace stderr
379+
```
380+
381+
Now you get full error trace addition to the error message. Naturally, this
382+
also works with assertions. You can configure their output with the flag
383+
`asserter`:
384+
385+
```
386+
your-app -asserter Debug
387+
```
388+
389+
That adds more information to the assertion statement, which in default is in
390+
production (`Prod`) mode, i.e., outputs a single-line assertion message.
391+
392+
All you need to do is to add `flag.Parse` to your `main` function.
393+
394+
#### Support for Cobra Flags
395+
396+
If you are using [cobra](https://github.com/spf13/cobra) you can still easily
397+
support packages like `err2` and `glog` and their flags.
398+
399+
1. Add std flag package to imports in `cmd/root.go`:
400+
401+
```go
402+
import (
403+
goflag "flag"
404+
...
405+
)
406+
```
407+
408+
1. Add the following to (usually) `cmd/root.go`'s `init` function's end:
409+
410+
```go
411+
func init() {
412+
...
413+
// NOTE! Very important. Adds support for std flag pkg users: glog, err2
414+
pflag.CommandLine.AddGoFlagSet(goflag.CommandLine)
415+
}
416+
```
417+
418+
1. And finally modify your `PersistentPreRunE` in `cmd/root.go` to something
419+
like:
420+
421+
```go
422+
PersistentPreRunE: func(cmd *cobra.Command, args []string) (err error) {
423+
defer err2.Handle(&err)
424+
425+
// NOTE! Very important. Adds support for std flag pkg users: glog, err2
426+
goflag.Parse()
427+
428+
try.To(goflag.Set("logtostderr", "true"))
429+
handleViperFlags(cmd) // local helper with envs
430+
glog.CopyStandardLogTo("ERROR") // for err2
431+
return nil
432+
},
433+
```
434+
435+
As a result you can have bunch of usable flags added to your CLI:
436+
437+
```
438+
Flags:
439+
--asserter asserter asserter: Plain, Prod, Dev, Debug (default Prod)
440+
--err2-log stream stream for logging: nil -> log pkg (default nil)
441+
--err2-panic-trace stream stream for panic tracing (default stderr)
442+
--err2-trace stream stream for error tracing: stderr, stdout (default nil)
443+
...
444+
```
445+
349446
## Code Snippets
350447
351448
Most of the repetitive code blocks are offered as code snippets. They are in
@@ -430,45 +527,13 @@ Please see the full version history from [CHANGELOG](./CHANGELOG.md).
430527
431528
### Latest Release
432529
433-
##### 0.9.41
434-
- Issue #18: **bug fixed**: noerr-handler had to be the last one of the err2
435-
handlers
436-
437-
##### 0.9.40
438-
- Significant performance boost for: `defer err2.Handle/Catch()`
439-
- **3x faster happy path than the previous version, which is now equal to
440-
simplest `defer` function in the `err`-returning function** . (Please see
441-
the `defer` benchmarks in the `err2_test.go` and run `make bench_reca`)
442-
- the solution caused a change to API, where the core reason is Go's
443-
optimization "bug". (We don't have confirmation yet.)
444-
- Changed API for deferred error handling: `defer err2.Handle/Catch()`
445-
- *Obsolete*:
446-
```go
447-
defer err2.Handle(&err, func() {}) // <- relaying closure to access err val
448-
```
449-
- Current version:
450-
```go
451-
defer err2.Handle(&err, func(err error) error { return err }) // not a closure
452-
```
453-
Because handler function is not relaying closures any more, it opens a new
454-
opportunity to use and build general helper functions: `err2.Noop`, etc.
455-
- Use auto-migration scripts especially for large code-bases. More information
456-
can be found in the `scripts/` directory's [readme file](./scripts/README.md).
457-
- Added a new (*experimental*) API:
458-
```go
459-
defer err2.Handle(&err, func(noerr bool) {
460-
assert.That(noerr) // noerr is always true!!
461-
doSomething()
462-
})
463-
```
464-
This is experimental because we aren't sure if this is something we want to
465-
have in the `err2` package.
466-
- Bug fixes: `ResultX.Logf()` now works as it should
467-
- More documentation
530+
##### 0.9.5
531+
- `flag` package support to set `err2` and `assert` package configuration
532+
- `err2.Catch` default mode is to log error
533+
- cleanup and refactoring, new tests and benchmarks
468534
469535
### Upcoming releases
470536
471-
##### 0.9.5
472-
- Idea: Go's standard lib's flag pkg integration (similar to `glog`)
473-
- Continue removing unused parts from `assert` pkg
474-
- More documentation, repairing for some sort of marketing
537+
##### 0.9.6
538+
- Continue removing unused parts and repairing for 1.0.0 release.
539+
- Always more and better documentation

0 commit comments

Comments
 (0)