From fb7b8262d41b2976ddbd5aa528fb9fa2190b62b3 Mon Sep 17 00:00:00 2001 From: Eric Bottard Date: Thu, 1 Jun 2017 16:30:03 +0200 Subject: [PATCH] Allow printing of the full stacktrace after an error Fixes #70 --- .../shell2/result/ThrowableResultHandler.java | 31 +++++++++++++ .../shell2/standard/commands/Stacktrace.java | 45 +++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 spring-shell2-standard-commands/src/main/java/org/springframework/shell2/standard/commands/Stacktrace.java diff --git a/spring-shell2-core/src/main/java/org/springframework/shell2/result/ThrowableResultHandler.java b/spring-shell2-core/src/main/java/org/springframework/shell2/result/ThrowableResultHandler.java index ec9e8d55..4ddbc27f 100644 --- a/spring-shell2-core/src/main/java/org/springframework/shell2/result/ThrowableResultHandler.java +++ b/spring-shell2-core/src/main/java/org/springframework/shell2/result/ThrowableResultHandler.java @@ -17,8 +17,12 @@ package org.springframework.shell2.result; import org.jline.utils.AttributedString; +import org.jline.utils.AttributedStringBuilder; import org.jline.utils.AttributedStyle; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; +import org.springframework.shell2.CommandRegistry; import org.springframework.shell2.ResultHandler; import org.springframework.stereotype.Component; @@ -30,9 +34,36 @@ import org.springframework.stereotype.Component; @Component public class ThrowableResultHandler extends TerminalAwareResultHandler implements ResultHandler { + /** + * The name of the command that may be used to print details about the last error. + */ + public static final String DETAILS_COMMAND_NAME = "stacktrace"; + + private Throwable lastError; + + @Autowired @Lazy + private CommandRegistry commandRegistry; + @Override public void handleResult(Throwable result) { + lastError = result; terminal.writer().println(new AttributedString(result.toString(), AttributedStyle.DEFAULT.foreground(AttributedStyle.RED)).toAnsi()); + if (commandRegistry.listCommands().containsKey(DETAILS_COMMAND_NAME)) { + terminal.writer().println( + new AttributedStringBuilder() + .append("Details of the error have been omitted. You can use the ", AttributedStyle.DEFAULT.foreground(AttributedStyle.RED)) + .append(DETAILS_COMMAND_NAME, AttributedStyle.DEFAULT.foreground(AttributedStyle.RED).bold()) + .append(" command to print the full stacktrace.", AttributedStyle.DEFAULT.foreground(AttributedStyle.RED)) + .toAnsi() + ); + } + } + + /** + * Return the last error that was dealt with by this result handler. + */ + public Throwable getLastError() { + return lastError; } } diff --git a/spring-shell2-standard-commands/src/main/java/org/springframework/shell2/standard/commands/Stacktrace.java b/spring-shell2-standard-commands/src/main/java/org/springframework/shell2/standard/commands/Stacktrace.java new file mode 100644 index 00000000..13418094 --- /dev/null +++ b/spring-shell2-standard-commands/src/main/java/org/springframework/shell2/standard/commands/Stacktrace.java @@ -0,0 +1,45 @@ +/* + * Copyright 2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.shell2.standard.commands; + +import org.jline.terminal.Terminal; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.shell2.result.ThrowableResultHandler; +import org.springframework.shell2.standard.ShellComponent; +import org.springframework.shell2.standard.ShellMethod; + +/** + * A command to display the full stacktrace when an error occurs. + */ +@ShellComponent +public class Stacktrace { + + @Autowired + private Terminal terminal; + + @Autowired + private ThrowableResultHandler throwableResultHandler; + + + @ShellMethod(value = ThrowableResultHandler.DETAILS_COMMAND_NAME, help = "Display the full stacktrace of the last error") + public void stacktrace() { + if (throwableResultHandler.getLastError() != null) { + throwableResultHandler.getLastError().printStackTrace(terminal.writer()); + } + } +}