Research
Security News
Malicious npm Package Targets Solana Developers and Hijacks Funds
A malicious npm package targets Solana developers, rerouting funds in 2% of transactions to a hardcoded address.
github.com/mpvl/errc
Package errc
simplifies error and defer handling.
go get github.com/mpvl/errc
Also note the sibling package go get github.com/mpvl/errd
. Package errc
probably looks more like a language feature would look like. Package errd
however is a bit safer to use as well as a bit faster.
Package errc
is a burner package, a proof-of-concept to analyze how to
improve error handling for future iterations of Go. The idiomatic way to
handle errors in Go looks like:
func foo() (err error) {
r, err := getReader()
if err != nil {
return err
}
defer r.Close()
// etc.
The implied promise of simplicity of this pattern, though a bit verbose, often does not hold. Take the following example:
func writeToGS(ctx context.Context, bucket, dst string, r io.Reader) (err error) {
client, err := storage.NewClient(ctx)
if err != nil {
return err
}
defer client.Close()
w := client.Bucket(bucket).Object(dst).NewWriter(ctx)
err = errPanicking
defer func() {
if err != nil {
_ = w.CloseWithError(err)
} else {
err = w.Close()
}
}
_, err = io.Copy(w, r) {
return err
}
This function atomically writes the contents of an io.Reader to a Google Cloud Storage file. It ensures the following:
w
is returned if there wasn't any error alreadyThe first condition is necessary to ensure any retry logic will know the file was not successfully written. The second condition ensures no partial file is written in case of a panic. A panic may occur, for instance, when the server is killed by a cluster manager because it uses too much memory.
Using package errc
, the same is achieved by:
func writeToGS(ctx context.Context, bucket, dst, src string) (err error) {
e := errc.Catch(&err)
defer e.Handle()
client, err := storage.NewClient(ctx)
e.Must(err)
e.Defer(client.Close, errc.Discard)
w := client.Bucket(bucket).Object(dst).NewWriter(ctx)
e.Defer(w.CloseWithError)
_, err = io.Copy(w, r)
e.Must(err)
}
In this case, the above guarantees are met by applying the idiomatic
check-and-defer pattern.
The handling of errors around panics, Must
and Defer
is such that
applying the check-and-defer pattern yields the correct results without much
further thought.
Package errc
defines a Handler type to allow inline processing of errors.
Suppose we want to use github.com/pkg/errors
to decorate errors.
A simple handler can be defined as:
type msg string
func (m msg) Handle(s errc.State, err error) error {
return errors.WithMessage(err, string(m))
}
This handler can then be used as follows:
func writeToGS(ctx context.Context, bucket, dst, src string) error {
e := errc.Catch(&err)
defer e.Handle()
client, err := storage.NewClient(ctx)
e.Must(err, msg("creating client failed"))
e.Defer(client.Close, errc.Discard)
w := client.Bucket(bucket).Object(dst).NewWriter(ctx)
e.Defer(w.CloseWithError)
_, err = io.Copy(w, r)
e.Must(err, msg("copy failed"))
return nil
}
It is also possible to pass a default Handler to the Catch function, which will be applied if no Handler is given at the point of detection.
As said, errc
is a "burner package".
The goal is to improve error handling focussing on semantics first, rather than
considering syntax first.
The main requirements for error handling addressed by errc
are:
github.com/pkg/errors
).The main errc
concept is that of an error funnel: a single variable associated
with each function in which the current error state is recorded.
It is very much like having a named error return argument in which to record
all errors, but ensuring that the following holds:
Must
or Defer
will only be recorded in
the error variable if the error variable is nil
,One could classify error values as recoverable errors while panics are
unrecoverable errors.
In practice things are a bit more subtle. Cleanup code that is called through
defers is still called after a panic.
Although easily ignored, it may be important for such code to consider a panic
as being in an erroring state.
However, by default in Go panic and errors are treated completely separately.
Package errc
preserves panic semantics, while also treating panics as an
error.
More specifically, a panic will keep unwinding until an explicit recover, while
at the same time it assigns a panic-related error to
the error variable to communicate that the function is currently in an erroring
state.
Package errc
uses Go's panic
and recover
mechanism to force the exit from
Run
if an error is encountered.
On top of that, package errc
manages its own defer state, which is
necessary to properly interweave error and defer handling.
Package errc
adds a defer block to do all its management.
If the original code only does error checking, this is a relatively
big price to pay.
If the original code already does a defer, the damage is limited.
If the original code uses multiple defers, package errc
may even be faster.
Passing string-type error handlers, like in the example on error handlers, causes an allocation. However, in 1.9 this special case does not incur noticeable overhead over passing a pre-allocated handler.
As errc
uses defer
, it does not work across goroutine boundaries.
In general, it is advisable not to pass an errc.Catcher
value as an argument
to any function call.
Package errc
is about exploring better ways and semantics for handling errors
and defers. The main goal here is to come up with a good improvement for Go 2.
FAQs
Unknown package
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
A malicious npm package targets Solana developers, rerouting funds in 2% of transactions to a hardcoded address.
Security News
Research
Socket researchers have discovered malicious npm packages targeting crypto developers, stealing credentials and wallet data using spyware delivered through typosquats of popular cryptographic libraries.
Security News
Socket's package search now displays weekly downloads for npm packages, helping developers quickly assess popularity and make more informed decisions.