Tags: calebcase/oops
Tags
trace: capture all callers The original intention was to capture all callers, but I misunderstood the API contract and it only captured the first N (where N was 10). This exposes and sets a higher chunk size (64) that is used for the initial buffer and subsequent increases to the buffer. The buffer will be increased by chunk size until it is large enough to hold the entire stack of callers.
Rework Namespaces This reworks namespaces to make them easier to use. Now most of the library functions are available as methods on the namespace. Namespaces now have roughly the same UX as the package itself. TraceSkipInternal is now also exported to make it consistent how many frames should be skipped to avoid reporting frames internal to the oops package itself.
nil checks on (typed) interfaces are an abomination
An interface is composed of both the type and value. When oops.Trace
returned the pointer *TraceError instead of the interface error the type
information was passed along. Unfortunately that meant when passing
*TraceError to a function that takes error values (e.g. Chain) the error
interface had non-empty type information. This meant that err == nil
would return false in such functions because interface{*oops.Trace, nil}
is not the same as interface{nil, nil}. This is unfortunate since it
means we can't follow the usual paradigm of returning concrete types and
accepting interfaces... Or at least we can't and still rely on the
widely accepted `err == nil` practice. The options for not checking nil
in this way are all deficient in some way (performance, convention).
Further reading for the curious:
https://dave.cheney.net/2017/08/09/typed-nils-in-go-2
Changing all the functions to return the interface error instead of the
concrete type was deemed to least problematic way to resolve the
situation. Now the naive check err == nil works as expected. Eventually
maybe Go2 will provide a solution to this situation that is less
painful.
namespace: use string directly
Instead of wrapping the string in a struct with one field use string
directly. This makes linters happy that would otherwise complain about
the use of unkeyed fields. Usage changes from `Namespace{"thing"}` to
`Namespace("thing")`.
PreviousNext