mirror of
https://github.com/garethgeorge/backrest.git
synced 2025-12-14 01:35:31 +00:00
97 lines
1.8 KiB
Go
97 lines
1.8 KiB
Go
package restic
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"os/exec"
|
|
)
|
|
|
|
const outputBufferLimit = 1000
|
|
|
|
type CmdError struct {
|
|
Command string
|
|
Err error
|
|
}
|
|
|
|
func (e *CmdError) Error() string {
|
|
m := fmt.Sprintf("command %q failed: %s", e.Command, e.Err.Error())
|
|
return m
|
|
}
|
|
|
|
func (e *CmdError) Unwrap() error {
|
|
return e.Err
|
|
}
|
|
|
|
func (e *CmdError) Is(target error) bool {
|
|
_, ok := target.(*CmdError)
|
|
return ok
|
|
}
|
|
|
|
// newCmdError creates a new error indicating that running a command failed.
|
|
func newCmdError(cmd *exec.Cmd, err error) *CmdError {
|
|
shortCmd := cmd.String()
|
|
if len(shortCmd) > 100 {
|
|
shortCmd = shortCmd[:100] + "..."
|
|
}
|
|
|
|
cerr := &CmdError{
|
|
Command: shortCmd,
|
|
Err: err,
|
|
}
|
|
return cerr
|
|
}
|
|
|
|
type ErrorWithOutput struct {
|
|
Err error
|
|
Output string
|
|
}
|
|
|
|
func (e *ErrorWithOutput) Error() string {
|
|
return fmt.Sprintf("%v\nOutput:\n%s", e.Err, e.Output)
|
|
}
|
|
|
|
func (e *ErrorWithOutput) Unwrap() error {
|
|
return e.Err
|
|
}
|
|
|
|
func (e *ErrorWithOutput) Is(target error) bool {
|
|
_, ok := target.(*ErrorWithOutput)
|
|
return ok
|
|
}
|
|
|
|
type errorMessageCollector struct {
|
|
Output *bytes.Buffer
|
|
DroppedBytes int
|
|
}
|
|
|
|
func (e *errorMessageCollector) Write(p []byte) (int, error) {
|
|
if e.Output == nil {
|
|
e.Output = &bytes.Buffer{}
|
|
}
|
|
if e.Output.Len() >= outputBufferLimit {
|
|
e.DroppedBytes += len(p)
|
|
return len(p), nil
|
|
}
|
|
return e.Output.Write(p)
|
|
}
|
|
|
|
func (e *errorMessageCollector) AddOutputToError(err error) error {
|
|
if e.Output == nil {
|
|
return err
|
|
}
|
|
if e.DroppedBytes > 0 {
|
|
return &ErrorWithOutput{
|
|
Err: err,
|
|
Output: fmt.Sprintf("%s\n... %d bytes truncated ...", e.Output.String(), e.DroppedBytes),
|
|
}
|
|
}
|
|
return &ErrorWithOutput{
|
|
Err: err,
|
|
Output: e.Output.String(),
|
|
}
|
|
}
|
|
|
|
func (e *errorMessageCollector) AddCmdOutputToError(cmd *exec.Cmd, err error) error {
|
|
return newCmdError(cmd, e.AddOutputToError(err))
|
|
}
|