From d924a7cb1aa88c7ef98f0bf1bdd3b1d33061b0ea Mon Sep 17 00:00:00 2001 From: zml Date: Sun, 6 Mar 2022 18:22:47 -0800 Subject: [PATCH] text-minimessage: Add stacktraces and more detail to legacy errors Closes #720 --- .../text/minimessage/ContextImpl.java | 6 +++--- .../internal/parser/ParsingExceptionImpl.java | 10 ++++++++- .../internal/parser/TokenParser.java | 21 +++++++++++++------ 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/ContextImpl.java b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/ContextImpl.java index fa800cb49..4d880c1d0 100644 --- a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/ContextImpl.java +++ b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/ContextImpl.java @@ -124,17 +124,17 @@ public UnaryOperator postProcessor() { @Override public @NotNull ParsingException newException(@NotNull final String message) { - return new ParsingExceptionImpl(message, this.message, null, EMPTY_TOKEN_ARRAY); + return new ParsingExceptionImpl(message, this.message, null, false, EMPTY_TOKEN_ARRAY); } @Override public @NotNull ParsingException newException(final @NotNull String message, final @NotNull ArgumentQueue tags) { - return new ParsingExceptionImpl(message, this.message, tagsToTokens(((ArgumentQueueImpl) tags).args)); + return new ParsingExceptionImpl(message, this.message, null, false, tagsToTokens(((ArgumentQueueImpl) tags).args)); } @Override public @NotNull ParsingException newException(final @NotNull String message, final @Nullable Throwable cause, final @NotNull ArgumentQueue tags) { - return new ParsingExceptionImpl(message, this.message, cause, tagsToTokens(((ArgumentQueueImpl) tags).args)); + return new ParsingExceptionImpl(message, this.message, cause, false, tagsToTokens(((ArgumentQueueImpl) tags).args)); } private static Token[] tagsToTokens(final List tags) { diff --git a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/internal/parser/ParsingExceptionImpl.java b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/internal/parser/ParsingExceptionImpl.java index f2778b674..6412d1a23 100644 --- a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/internal/parser/ParsingExceptionImpl.java +++ b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/internal/parser/ParsingExceptionImpl.java @@ -40,6 +40,7 @@ public class ParsingExceptionImpl extends ParsingException { private final String originalText; private Token @NotNull [] tokens; + private final boolean withStackTrace; /** * Create a new parsing exception. @@ -57,6 +58,7 @@ public ParsingExceptionImpl( super(message); this.tokens = tokens; this.originalText = originalText; + this.withStackTrace = false; } /** @@ -65,6 +67,7 @@ public ParsingExceptionImpl( * @param message the detail message * @param originalText the original text which was parsed * @param cause the cause + * @param withStackTrace whether to generate a stacktrace * @param tokens the token which caused the error * @since 4.10.0 */ @@ -72,11 +75,13 @@ public ParsingExceptionImpl( final String message, final @Nullable String originalText, final @Nullable Throwable cause, + final boolean withStackTrace, final @NotNull Token @NotNull ... tokens ) { super(message, cause); this.tokens = tokens; this.originalText = originalText; + this.withStackTrace = withStackTrace; } @Override @@ -142,7 +147,10 @@ private String arrow() { } @Override - public ParsingExceptionImpl fillInStackTrace() { // no stacktrace + public Throwable fillInStackTrace() { + if (this.withStackTrace) { + return super.fillInStackTrace(); + } return this; } diff --git a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/internal/parser/TokenParser.java b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/internal/parser/TokenParser.java index 5ed991292..9c06c84c8 100644 --- a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/internal/parser/TokenParser.java +++ b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/internal/parser/TokenParser.java @@ -158,12 +158,21 @@ public static void parseString(final String message, final MatchedTokenConsumer< final int length = message.length(); for (int i = 0; i < length; i++) { final int codePoint = message.codePointAt(i); - if (codePoint == '§') { - throw new ParsingExceptionImpl( - "Legacy formatting codes have been detected in a component - this is unsupported behaviour. Please refer to the Adventure documentation (https://docs.adventure.kyori.net) for more information.", - message, - new Token(i, i + 2, TokenType.TEXT) - ); + if (codePoint == '§' && i + 1 < length) { + final int nextChar = Character.toLowerCase(message.codePointAt(i + 1)); + // Only throw an exception if the next character is actually going to make a legacy color code + if ((nextChar >= '0' && nextChar <= '9') + || (nextChar >= 'a' && nextChar <= 'f') + || nextChar == 'r' + || (nextChar >= 'k' && nextChar <= 'o')) { + throw new ParsingExceptionImpl( + "Legacy formatting codes have been detected in a MiniMessage string - this is unsupported behaviour. Please refer to the Adventure documentation (https://docs.adventure.kyori.net) for more information.", + message, + null, + true, + new Token(i, i + 2, TokenType.TEXT) + ); + } } if (!Character.isBmpCodePoint(codePoint)) {