File: do.go

package info (click to toggle)
golang-github-efficientgo-core 1.0.0~rc3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 580 kB
  • sloc: makefile: 68
file content (46 lines) | stat: -rw-r--r-- 1,174 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
// Copyright (c) The EfficientGo Authors.
// Licensed under the Apache License 2.0.

// Initially copied from Thanos
//
// Copyright (c) The Thanos Authors.
// Licensed under the Apache License 2.0.

package errcapture

import (
	"io"
	"os"

	"github.com/efficientgo/core/errors"
	"github.com/efficientgo/core/merrors"
)

type doFunc func() error

// Do runs function and on error return error by argument including the given error (usually
// from caller function).
func Do(err *error, doer doFunc, format string, a ...interface{}) {
	derr := doer()
	if err == nil {
		return
	}

	// For os closers, it's a common case to double close. From reliability purpose this is not a problem it may only indicate
	// surprising execution path.
	if errors.Is(derr, os.ErrClosed) {
		return
	}

	*err = merrors.New(*err, errors.Wrapf(derr, format, a...)).Err()
}

// ExhaustClose closes the io.ReadCloser with error capture but exhausts the reader before.
func ExhaustClose(err *error, r io.ReadCloser, format string, a ...interface{}) {
	_, copyErr := io.Copy(io.Discard, r)

	Do(err, r.Close, format, a...)

	// Prepend the io.Copy error.
	*err = merrors.New(copyErr, *err).Err()
}