Print errors with some context about the remote server

This commit is contained in:
Neil Macneale IV
2023-05-18 16:46:07 -07:00
parent d5214af321
commit 4aeaf71f78
2 changed files with 49 additions and 23 deletions
+47 -23
View File
@@ -234,7 +234,7 @@ func (cmd SqlCmd) Exec(ctx context.Context, commandStr string, args []string, dE
fi, err := os.Stdin.Stat()
if err != nil {
if !osutil.IsWindows {
return HandleVErrAndExitCode(errhand.BuildDError("Couldn't stat STDIN. This is a bug.").Build(), usage)
return sqlHandleVErrAndExitCode(queryist, errhand.BuildDError("Couldn't stat STDIN. This is a bug.").Build(), usage)
}
} else {
isTty = fi.Mode()&os.ModeCharDevice != 0
@@ -247,11 +247,11 @@ func (cmd SqlCmd) Exec(ctx context.Context, commandStr string, args []string, dE
isTty = false
input, err = os.OpenFile(fileInput, os.O_RDONLY, os.ModePerm)
if err != nil {
return HandleVErrAndExitCode(errhand.BuildDError("couldn't open file %s", fileInput).Build(), usage)
return sqlHandleVErrAndExitCode(queryist, errhand.BuildDError("couldn't open file %s", fileInput).Build(), usage)
}
info, err := os.Stat(fileInput)
if err != nil {
return HandleVErrAndExitCode(errhand.BuildDError("couldn't get file size %s", fileInput).Build(), usage)
return sqlHandleVErrAndExitCode(queryist, errhand.BuildDError("couldn't get file size %s", fileInput).Build(), usage)
}
// initialize fileReadProg global variable if there is a file to process queries from
@@ -262,23 +262,23 @@ func (cmd SqlCmd) Exec(ctx context.Context, commandStr string, args []string, dE
if isTty {
err := execShell(sqlCtx, queryist, format)
if err != nil {
return HandleVErrAndExitCode(errhand.VerboseErrorFromError(err), usage)
return sqlHandleVErrAndExitCode(queryist, errhand.VerboseErrorFromError(err), usage)
}
} else if runInBatchMode {
se, ok := queryist.(*engine.SqlEngine)
if !ok {
misuse := fmt.Errorf("Using batch with non-local access pattern. Stop server if it is running")
return HandleVErrAndExitCode(errhand.VerboseErrorFromError(misuse), usage)
return sqlHandleVErrAndExitCode(queryist, errhand.VerboseErrorFromError(misuse), usage)
}
verr := execBatch(sqlCtx, se, input, continueOnError, format)
if verr != nil {
return HandleVErrAndExitCode(verr, usage)
return sqlHandleVErrAndExitCode(queryist, verr, usage)
}
} else {
err := execMultiStatements(sqlCtx, queryist, input, continueOnError, format)
if err != nil {
return HandleVErrAndExitCode(errhand.VerboseErrorFromError(err), usage)
return sqlHandleVErrAndExitCode(queryist, errhand.VerboseErrorFromError(err), usage)
}
}
}
@@ -286,6 +286,30 @@ func (cmd SqlCmd) Exec(ctx context.Context, commandStr string, args []string, dE
return 0
}
// sqlHandleVErrAndExitCode is a helper function to print errors to the user. Currently, the Queryist interface is used to
// determine if this is a local or remote execution. This is hacky, and too simplistic. We should possibly add an error
// messaging interface to the CliContext.
func sqlHandleVErrAndExitCode(queryist cli.Queryist, verr errhand.VerboseError, usage cli.UsagePrinter) int {
if verr != nil {
if msg := verr.Verbose(); strings.TrimSpace(msg) != "" {
if _, ok := queryist.(*engine.SqlEngine); !ok {
// We are in a context where we are attempting to connect to a remote database. These errors
// are unstructured, so we add some additional context around them.
msg = fmt.Sprintf("Error connecting to remote database: \"%s\".", msg)
}
cli.PrintErrln(msg)
}
if verr.ShouldPrintUsage() {
usage()
}
return 1
}
return 0
}
// handleLegacyArguments is a temporary function to parse args, and print a error and explanation when the old form is provided.
func (cmd SqlCmd) handleLegacyArguments(ap *argparser.ArgParser, commandStr string, args []string) (*argparser.ArgParseResults, error) {
@@ -327,19 +351,19 @@ func (cmd SqlCmd) handleLegacyArguments(ap *argparser.ArgParser, commandStr stri
func listSavedQueries(ctx *sql.Context, qryist cli.Queryist, dEnv *env.DoltEnv, format engine.PrintResultFormat, usage cli.UsagePrinter) int {
if !dEnv.Valid() {
return HandleVErrAndExitCode(errhand.BuildDError("error: --%s must be used in a dolt database directory.", listSavedFlag).Build(), usage)
return sqlHandleVErrAndExitCode(qryist, errhand.BuildDError("error: --%s must be used in a dolt database directory.", listSavedFlag).Build(), usage)
}
workingRoot, err := dEnv.WorkingRoot(ctx)
if err != nil {
return HandleVErrAndExitCode(errhand.VerboseErrorFromError(err), usage)
return sqlHandleVErrAndExitCode(qryist, errhand.VerboseErrorFromError(err), usage)
}
hasQC, err := workingRoot.HasTable(ctx, doltdb.DoltQueryCatalogTableName)
if err != nil {
verr := errhand.BuildDError("error: Failed to read from repository.").AddCause(err).Build()
return HandleVErrAndExitCode(verr, usage)
return sqlHandleVErrAndExitCode(qryist, verr, usage)
}
if !hasQC {
@@ -347,27 +371,27 @@ func listSavedQueries(ctx *sql.Context, qryist cli.Queryist, dEnv *env.DoltEnv,
}
query := "SELECT * FROM " + doltdb.DoltQueryCatalogTableName
return HandleVErrAndExitCode(execQuery(ctx, qryist, query, format), usage)
return sqlHandleVErrAndExitCode(qryist, execQuery(ctx, qryist, query, format), usage)
}
func executeSavedQuery(ctx *sql.Context, qryist cli.Queryist, dEnv *env.DoltEnv, savedQueryName string, format engine.PrintResultFormat, usage cli.UsagePrinter) int {
if !dEnv.Valid() {
return HandleVErrAndExitCode(errhand.BuildDError("error: --%s must be used in a dolt database directory.", executeFlag).Build(), usage)
return sqlHandleVErrAndExitCode(qryist, errhand.BuildDError("error: --%s must be used in a dolt database directory.", executeFlag).Build(), usage)
}
workingRoot, err := dEnv.WorkingRoot(ctx)
if err != nil {
return HandleVErrAndExitCode(errhand.VerboseErrorFromError(err), usage)
return sqlHandleVErrAndExitCode(qryist, errhand.VerboseErrorFromError(err), usage)
}
sq, err := dtables.RetrieveFromQueryCatalog(ctx, workingRoot, savedQueryName)
if err != nil {
return HandleVErrAndExitCode(errhand.VerboseErrorFromError(err), usage)
return sqlHandleVErrAndExitCode(qryist, errhand.VerboseErrorFromError(err), usage)
}
cli.PrintErrf("Executing saved query '%s':\n%s\n", savedQueryName, sq.Query)
return HandleVErrAndExitCode(execQuery(ctx, qryist, sq.Query, format), usage)
return sqlHandleVErrAndExitCode(qryist, execQuery(ctx, qryist, sq.Query, format), usage)
}
func queryMode(
@@ -389,19 +413,19 @@ func queryMode(
se, ok := qryist.(*engine.SqlEngine)
if !ok {
misuse := fmt.Errorf("Using batch with non-local access pattern. Stop server if it is running")
return HandleVErrAndExitCode(errhand.VerboseErrorFromError(misuse), usage)
return sqlHandleVErrAndExitCode(se, errhand.VerboseErrorFromError(misuse), usage)
}
batchInput := strings.NewReader(query)
verr := execBatch(ctx, se, batchInput, continueOnError, format)
if verr != nil {
return HandleVErrAndExitCode(verr, usage)
return sqlHandleVErrAndExitCode(qryist, verr, usage)
}
} else {
input := strings.NewReader(query)
err := execMultiStatements(ctx, qryist, input, continueOnError, format)
if err != nil {
return HandleVErrAndExitCode(errhand.VerboseErrorFromError(err), usage)
return sqlHandleVErrAndExitCode(qryist, errhand.VerboseErrorFromError(err), usage)
}
}
@@ -410,30 +434,30 @@ func queryMode(
func execSaveQuery(ctx *sql.Context, dEnv *env.DoltEnv, qryist cli.Queryist, apr *argparser.ArgParseResults, query string, format engine.PrintResultFormat, usage cli.UsagePrinter) int {
if !dEnv.Valid() {
return HandleVErrAndExitCode(errhand.BuildDError("error: --%s must be used in a dolt database directory.", saveFlag).Build(), usage)
return sqlHandleVErrAndExitCode(qryist, errhand.BuildDError("error: --%s must be used in a dolt database directory.", saveFlag).Build(), usage)
}
saveName := apr.GetValueOrDefault(saveFlag, "")
verr := execQuery(ctx, qryist, query, format)
if verr != nil {
return HandleVErrAndExitCode(verr, usage)
return sqlHandleVErrAndExitCode(qryist, verr, usage)
}
workingRoot, err := dEnv.WorkingRoot(ctx)
if err != nil {
return HandleVErrAndExitCode(errhand.BuildDError("error: failed to get working root").AddCause(err).Build(), usage)
return sqlHandleVErrAndExitCode(qryist, errhand.BuildDError("error: failed to get working root").AddCause(err).Build(), usage)
}
saveMessage := apr.GetValueOrDefault(messageFlag, "")
newRoot, verr := saveQuery(ctx, workingRoot, query, saveName, saveMessage)
if verr != nil {
return HandleVErrAndExitCode(verr, usage)
return sqlHandleVErrAndExitCode(qryist, verr, usage)
}
err = dEnv.UpdateWorkingRoot(ctx, newRoot)
if err != nil {
return HandleVErrAndExitCode(errhand.BuildDError("error: failed to update working root").AddCause(err).Build(), usage)
return sqlHandleVErrAndExitCode(qryist, errhand.BuildDError("error: failed to update working root").AddCause(err).Build(), usage)
}
return 0
+2
View File
@@ -1498,8 +1498,10 @@ databases:
cd repo2
dolt sql -q "create table a (x int primary key)"
start_sql_server
run dolt --verbose-engine-setup sql -q "create table b (x int primary key)"
[ "$status" -eq 1 ]
[[ "$output" =~ "Error connecting to remote database" ]] || false
[[ "$output" =~ "User not found 'root'" ]] || false
run dolt --verbose-engine-setup --user dolt sql -q "create table b (x int primary key)"