tools: display error context when it exists (#749)
For example when failing to decode toml, display the context around the error and the location of the problem.
This commit is contained in:
+13
-1
@@ -2,11 +2,14 @@ package cli
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"errors"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/pelletier/go-toml/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ConvertFn func(r io.Reader, w io.Writer) error
|
type ConvertFn func(r io.Reader, w io.Writer) error
|
||||||
@@ -28,7 +31,16 @@ func (p *Program) Execute() {
|
|||||||
func (p *Program) main(files []string, input io.Reader, output, error io.Writer) int {
|
func (p *Program) main(files []string, input io.Reader, output, error io.Writer) int {
|
||||||
err := p.run(files, input, output)
|
err := p.run(files, input, output)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(error, err.Error())
|
|
||||||
|
var derr *toml.DecodeError
|
||||||
|
if errors.As(err, &derr) {
|
||||||
|
fmt.Fprintln(error, derr.String())
|
||||||
|
row, col := derr.Position()
|
||||||
|
fmt.Fprintln(error, "error occurred at row", row, "column", col)
|
||||||
|
} else {
|
||||||
|
fmt.Fprintln(error, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/pelletier/go-toml/v2"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
@@ -47,6 +48,21 @@ func TestProcessMainStdinErr(t *testing.T) {
|
|||||||
assert.NotEmpty(t, stderr.String())
|
assert.NotEmpty(t, stderr.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestProcessMainStdinDecodeErr(t *testing.T) {
|
||||||
|
stdout := new(bytes.Buffer)
|
||||||
|
stderr := new(bytes.Buffer)
|
||||||
|
input := strings.NewReader("this is the input")
|
||||||
|
|
||||||
|
exit := processMain([]string{}, input, stdout, stderr, func(r io.Reader, w io.Writer) error {
|
||||||
|
var v interface{}
|
||||||
|
return toml.Unmarshal([]byte(`qwe = 001`), &v)
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.Equal(t, -1, exit)
|
||||||
|
assert.Empty(t, stdout.String())
|
||||||
|
assert.Contains(t, stderr.String(), "error occurred at")
|
||||||
|
}
|
||||||
|
|
||||||
func TestProcessMainFileExists(t *testing.T) {
|
func TestProcessMainFileExists(t *testing.T) {
|
||||||
tmpfile, err := ioutil.TempFile("", "example")
|
tmpfile, err := ioutil.TempFile("", "example")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|||||||
Reference in New Issue
Block a user