Skip to content

Commit

Permalink
Parse kopia errors (#1973)
Browse files Browse the repository at this point in the history
* Parse kopia errors

* Add couple more cases

---------

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
  • Loading branch information
e-sumin and mergify[bot] committed Apr 21, 2023
1 parent eb22cae commit f74570f
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 0 deletions.
23 changes: 23 additions & 0 deletions pkg/kopia/command/parse_command_output.go
Original file line number Diff line number Diff line change
Expand Up @@ -389,3 +389,26 @@ func IsEqualSnapshotCreateStats(a, b *SnapshotCreateStats) bool {
a.SizeEstimatedB == b.SizeEstimatedB &&
a.ProgressPercent == b.ProgressPercent
}

var ANSIEscapeCode = regexp.MustCompile(`\x1b[^m]*?m`)
var kopiaErrorPattern = regexp.MustCompile(`(?:ERROR\s+|.*\<ERROR\>\s*|error\s+)(.*)`)

// ErrorFromOutput parses the output of a kopia and returns an error, if found
func ErrorsFromOutput(output string) []error {
if output == "" {
return nil
}

var err []error

lines := regexp.MustCompile("[\r\n]").Split(output, -1)
for _, l := range lines {
clean := ANSIEscapeCode.ReplaceAllString(l, "") // Strip all ANSI escape codes from line
match := kopiaErrorPattern.FindAllStringSubmatch(clean, 1)
if len(match) > 0 {
err = append(err, errors.New(match[0][1]))
}
}

return err
}
28 changes: 28 additions & 0 deletions pkg/kopia/command/parse_command_output_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,34 @@ func (kParse *KopiaParseUtilsTestSuite) TestIsEqualSnapshotCreateStats(c *C) {
}
}

func (kParse *KopiaParseUtilsTestSuite) TestErrorsFromOutput(c *C) {
for caseIdx, tc := range []struct {
log string
expectedErrors []string
}{
// Some real error case
{"ERROR open repository: repository is not connected. See https://kopia.io/docs/repositories/", []string{"open repository: repository is not connected. See https://kopia.io/docs/repositories/"}},
// The same as previous but with coloured ERROR word
{string([]byte{27, 91, 51, 49, 109, 69, 82, 82, 79, 82, 27, 91, 48, 109, 32, 111, 112, 101, 110, 32, 114, 101, 112, 111, 115, 105, 116, 111, 114, 121, 58, 32, 114, 101, 112, 111, 115, 105, 116, 111, 114, 121, 32, 105, 115, 32, 110, 111, 116, 32, 99, 111, 110, 110, 101, 99, 116, 101, 100, 46}), []string{"open repository: repository is not connected."}},
// Multiple error lines (seems not possible in real life, but just to cover this possibility)
{"ERROR open repository: repository is not connected. See https://kopia.io/docs/repositories/\r\nERROR another error", []string{"open repository: repository is not connected. See https://kopia.io/docs/repositories/", "another error"}},
// Error surrounded by other output
{"some text\r\nERROR open repository: repository is not connected. See https://kopia.io/docs/repositories/\r\nanother text line", []string{"open repository: repository is not connected. See https://kopia.io/docs/repositories/"}},
// No error in output
{"some text\r\nanother text line", []string{}},
{" 2009-11-10 23:00:00 UTC <ERROR> some error\n", []string{"some error"}},
{"error setting attributes: could not change owner/group", []string{"setting attributes: could not change owner/group"}},
{"error restoring: restore error: error copying: copy file: error creating file:", []string{"restoring: restore error: error copying: copy file: error creating file:"}},
} {
errs := ErrorsFromOutput(tc.log)
fc := Commentf("Failed for case #%v. Log: %s", caseIdx, tc.log)
c.Check(len(errs), Equals, len(tc.expectedErrors), fc)
for i, e := range errs {
c.Check(e.Error(), Equals, tc.expectedErrors[i], fc)
}
}
}

func marshalManifestList(c *C, manifestList []*snapshot.Manifest) string {
c.Assert(manifestList, NotNil)

Expand Down

0 comments on commit f74570f

Please sign in to comment.