Skip to content

Commit

Permalink
Format CLI error messages
Browse files Browse the repository at this point in the history
Error message is now colored in red to be more descriptive.

Stacktrace is displayed when --debug command line option is used.
  • Loading branch information
wendigo committed Jul 19, 2023
1 parent bb88cbd commit c597618
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ public class ClientOptions
private static final String DEFAULT_VALUE = "(default: ${DEFAULT-VALUE})";
private static final String SERVER_DEFAULT = "localhost:8080";
private static final String SOURCE_DEFAULT = "trino-cli";
static final String DEBUG_OPTION_NAME = "--debug";

@Parameters(paramLabel = "URL", description = "Trino server URL", arity = "0..1")
public Optional<String> url;
Expand Down Expand Up @@ -207,7 +208,7 @@ public class ClientOptions
@Option(names = {"-f", "--file"}, paramLabel = "<file>", description = "Execute statements from file and exit")
public String file;

@Option(names = "--debug", paramLabel = "<debug>", description = "Enable debug information")
@Option(names = DEBUG_OPTION_NAME, paramLabel = "<debug>", description = "Enable debug information")
public boolean debug;

@Option(names = "--history-file", paramLabel = "<historyFile>", defaultValue = "${env:TRINO_HISTORY_FILE:-${sys:user.home}/.trino_history}", description = "Path to the history file " + DEFAULT_VALUE)
Expand Down
6 changes: 2 additions & 4 deletions client/trino-cli/src/main/java/io/trino/cli/Console.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
import static io.trino.cli.TerminalUtils.getTerminal;
import static io.trino.cli.TerminalUtils.isRealTerminal;
import static io.trino.cli.TerminalUtils.terminalEncoding;
import static io.trino.cli.Trino.formatCliErrorMessage;
import static io.trino.client.ClientSession.stripTransactionId;
import static io.trino.sql.parser.StatementSplitter.Statement;
import static io.trino.sql.parser.StatementSplitter.isEmptyStatement;
Expand Down Expand Up @@ -420,10 +421,7 @@ private static boolean process(
return success;
}
catch (RuntimeException e) {
System.err.println("Error running command: " + e.getMessage());
if (queryRunner.isDebug()) {
e.printStackTrace(System.err);
}
System.err.println(formatCliErrorMessage(e, queryRunner.isDebug()));
return false;
}
}
Expand Down
29 changes: 28 additions & 1 deletion client/trino-cli/src/main/java/io/trino/cli/Trino.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
import io.trino.cli.ClientOptions.ClientExtraCredential;
import io.trino.cli.ClientOptions.ClientResourceEstimate;
import io.trino.cli.ClientOptions.ClientSessionProperty;
import org.jline.utils.AttributedStringBuilder;
import org.jline.utils.AttributedStyle;
import picocli.CommandLine;
import picocli.CommandLine.IVersionProvider;

Expand All @@ -31,7 +33,10 @@
import static com.google.common.base.MoreObjects.firstNonNull;
import static com.google.common.base.StandardSystemProperty.USER_HOME;
import static com.google.common.base.Strings.emptyToNull;
import static com.google.common.base.Throwables.getStackTraceAsString;
import static io.trino.cli.ClientOptions.DEBUG_OPTION_NAME;
import static java.lang.System.getenv;
import static java.util.regex.Pattern.quote;

public final class Trino
{
Expand All @@ -50,12 +55,34 @@ public static CommandLine createCommandLine(Object command)
.registerConverter(ClientSessionProperty.class, ClientSessionProperty::new)
.registerConverter(ClientExtraCredential.class, ClientExtraCredential::new)
.registerConverter(HostAndPort.class, HostAndPort::fromString)
.registerConverter(Duration.class, Duration::valueOf);
.registerConverter(Duration.class, Duration::valueOf)
.setExecutionExceptionHandler((e, cmd, parseResult) -> {
System.err.println(formatCliErrorMessage(e, parseResult.hasMatchedOption(DEBUG_OPTION_NAME)));
return 1;
});

getConfigFile().ifPresent(file -> ValidatingPropertiesDefaultProvider.attach(commandLine, file));
return commandLine;
}

public static String formatCliErrorMessage(Throwable throwable, boolean debug)
{
AttributedStringBuilder builder = new AttributedStringBuilder();
if (debug) {
builder.append(throwable.getClass().getName()).append(": ");
}

builder.append(throwable.getMessage(), AttributedStyle.BOLD.foreground(AttributedStyle.RED));

if (debug) {
String messagePattern = quote(throwable.getClass().getName() + ": " + throwable.getMessage());
String stackTraceWithoutMessage = getStackTraceAsString(throwable).replaceFirst(messagePattern, "");
builder.append(stackTraceWithoutMessage);
}

return builder.toAnsi();
}

private static Optional<File> getConfigFile()
{
return getConfigSearchPaths()
Expand Down

0 comments on commit c597618

Please sign in to comment.