Skip to content

Commit 03a9f91

Browse files
author
Marcin Kielar
committed
Improved handling of throwables in message formatting.
#390 Signed-off-by: Marcin Kielar <[email protected]>
1 parent 8c4ea8f commit 03a9f91

File tree

9 files changed

+44
-712
lines changed

9 files changed

+44
-712
lines changed

slf4j-api/src/main/java/org/slf4j/helpers/AbstractLogger.java

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -395,13 +395,7 @@ private void handle2ArgsCall(Level level, Marker marker, String msg, Object arg1
395395
}
396396

397397
private void handleArgArrayCall(Level level, Marker marker, String msg, Object[] args) {
398-
Throwable throwableCandidate = MessageFormatter.getThrowableCandidate(args);
399-
if (throwableCandidate != null) {
400-
Object[] trimmedCopy = MessageFormatter.trimmedCopy(args);
401-
handleNormalizedLoggingCall(level, marker, msg, trimmedCopy, throwableCandidate);
402-
} else {
403-
handleNormalizedLoggingCall(level, marker, msg, args, null);
404-
}
398+
handleNormalizedLoggingCall(level, marker, msg, args, null);
405399
}
406400

407401
abstract protected String getFullyQualifiedCallerName();
@@ -411,6 +405,8 @@ private void handleArgArrayCall(Level level, Marker marker, String msg, Object[]
411405
*
412406
* <p>This method assumes that the separation of the args array into actual
413407
* objects and a throwable has been already operated.
408+
*
409+
* TODO: I think it should accept formatted message rather than pattern and arguments.
414410
*
415411
* @param level the SLF4J level for this event
416412
* @param marker The marker to be used for this event, may be null.

slf4j-api/src/main/java/org/slf4j/helpers/FormattingTuple.java

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,26 +35,20 @@ public class FormattingTuple {
3535

3636
private final String message;
3737
private final Throwable throwable;
38-
private final Object[] argArray;
3938

4039
public FormattingTuple(String message) {
41-
this(message, null, null);
40+
this(message, null);
4241
}
4342

44-
public FormattingTuple(String message, Object[] argArray, Throwable throwable) {
43+
public FormattingTuple(String message, Throwable throwable) {
4544
this.message = message;
4645
this.throwable = throwable;
47-
this.argArray = argArray;
4846
}
4947

5048
public String getMessage() {
5149
return message;
5250
}
5351

54-
public Object[] getArgArray() {
55-
return argArray;
56-
}
57-
5852
public Throwable getThrowable() {
5953
return throwable;
6054
}

slf4j-api/src/main/java/org/slf4j/helpers/MessageFormatter.java

Lines changed: 23 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -152,12 +152,7 @@ final public static FormattingTuple format(final String messagePattern, Object a
152152
}
153153

154154
final public static FormattingTuple arrayFormat(final String messagePattern, final Object[] argArray) {
155-
Throwable throwableCandidate = MessageFormatter.getThrowableCandidate(argArray);
156-
Object[] args = argArray;
157-
if (throwableCandidate != null) {
158-
args = MessageFormatter.trimmedCopy(argArray);
159-
}
160-
return arrayFormat(messagePattern, args, throwableCandidate);
155+
return arrayFormat(messagePattern, argArray, null);
161156
}
162157

163158
/**
@@ -166,26 +161,40 @@ final public static FormattingTuple arrayFormat(final String messagePattern, fin
166161
* @param messagePattern
167162
* @param argArray
168163
*/
164+
@Deprecated
169165
final public static String basicArrayFormat(final String messagePattern, final Object[] argArray) {
170166
FormattingTuple ft = arrayFormat(messagePattern, argArray, null);
171167
return ft.getMessage();
172168
}
173169

174-
public static String basicArrayFormat(NormalizedParameters np) {
175-
return basicArrayFormat(np.getMessage(), np.getArguments());
170+
/** Resolves throwable to be used in log message.
171+
*
172+
* @param index index of first array entry that was not bound to format placeholder
173+
*/
174+
final static Throwable resolveThrowable(final Object[] argArray, final int index, final Throwable throwable) {
175+
if (throwable != null) {
176+
return throwable;
177+
}
178+
if(argArray != null && argArray.length > index) {
179+
final Object lastEntry = argArray[argArray.length - 1];
180+
if (lastEntry instanceof Throwable) {
181+
return (Throwable) lastEntry;
182+
}
183+
}
184+
return null;
176185
}
177186

178187
final public static FormattingTuple arrayFormat(final String messagePattern, final Object[] argArray, Throwable throwable) {
179188

180189
if (messagePattern == null) {
181-
return new FormattingTuple(null, argArray, throwable);
190+
return new FormattingTuple(null, resolveThrowable(argArray, 0, throwable));
182191
}
183192

184193
if (argArray == null) {
185-
return new FormattingTuple(messagePattern);
194+
return new FormattingTuple(messagePattern, throwable);
186195
}
187196

188-
int i = 0;
197+
int i = 0; // index in the pattern
189198
int j;
190199
// use string builder for better multicore performance
191200
StringBuilder sbuf = new StringBuilder(messagePattern.length() + 50);
@@ -198,11 +207,11 @@ final public static FormattingTuple arrayFormat(final String messagePattern, fin
198207
if (j == -1) {
199208
// no more variables
200209
if (i == 0) { // this is a simple string
201-
return new FormattingTuple(messagePattern, argArray, throwable);
210+
return new FormattingTuple(messagePattern, resolveThrowable(argArray, L, throwable));
202211
} else { // add the tail string which contains no variables and return
203212
// the result.
204213
sbuf.append(messagePattern, i, messagePattern.length());
205-
return new FormattingTuple(sbuf.toString(), argArray, throwable);
214+
return new FormattingTuple(sbuf.toString(), resolveThrowable(argArray, L, throwable));
206215
}
207216
} else {
208217
if (isEscapedDelimeter(messagePattern, j)) {
@@ -229,7 +238,7 @@ final public static FormattingTuple arrayFormat(final String messagePattern, fin
229238
}
230239
// append the characters following the last {} pair.
231240
sbuf.append(messagePattern, i, messagePattern.length());
232-
return new FormattingTuple(sbuf.toString(), argArray, throwable);
241+
return new FormattingTuple(sbuf.toString(), throwable);
233242
}
234243

235244
final static boolean isEscapedDelimeter(String messagePattern, int delimeterStartIndex) {
@@ -402,29 +411,4 @@ private static void doubleArrayAppend(StringBuilder sbuf, double[] a) {
402411
}
403412
sbuf.append(']');
404413
}
405-
406-
/**
407-
* Helper method to determine if an {@link Object} array contains a {@link Throwable} as last element
408-
*
409-
* @param argArray
410-
* The arguments off which we want to know if it contains a {@link Throwable} as last element
411-
* @return if the last {@link Object} in argArray is a {@link Throwable} this method will return it,
412-
* otherwise it returns null
413-
*/
414-
public static Throwable getThrowableCandidate(final Object[] argArray) {
415-
return NormalizedParameters.getThrowableCandidate(argArray);
416-
}
417-
418-
/**
419-
* Helper method to get all but the last element of an array
420-
*
421-
* @param argArray
422-
* The arguments from which we want to remove the last element
423-
*
424-
* @return a copy of the array without the last element
425-
*/
426-
public static Object[] trimmedCopy(final Object[] argArray) {
427-
return NormalizedParameters.trimmedCopy(argArray);
428-
}
429-
430414
}

slf4j-api/src/main/java/org/slf4j/helpers/NormalizedParameters.java

Lines changed: 0 additions & 116 deletions
This file was deleted.

0 commit comments

Comments
 (0)