@@ -94,7 +94,7 @@ public Result onServerError(final Context context, final Throwable throwable) { |
94 | 94 |
|
95 | 95 | final String subHeaderError; |
96 | 96 | final int lineNumberFromZero; |
97 | | - final List<FileLine> fileLineList; |
| 97 | + final PartialFileContent partialFileContent; |
98 | 98 | if (throwable.getClass() == TemplateException.RenderingFailure.class) { |
99 | 99 | // Template rendering error |
100 | 100 | final TemplateException.RenderingFailure renderingFailure = (TemplateException.RenderingFailure) throwable; |
@@ -104,7 +104,11 @@ public Result onServerError(final Context context, final Throwable throwable) { |
104 | 104 | subHeaderError = javaFilepathOptional.map(Path::toString).orElse(renderingFailure.getTemplateName()) |
105 | 105 | + StringConstants.COLON |
106 | 106 | + lineNumberFromZero; |
107 | | - fileLineList = javaFilepathOptional.map(path -> retrievePartialFileContent(path, lineNumberFromZero)).orElseGet(ArrayList::new); |
| 107 | + |
| 108 | + final List<FileLine> fileLineList = javaFilepathOptional |
| 109 | + .map(path -> retrievePartialFileContent(path, lineNumberFromZero)) |
| 110 | + .orElseGet(ArrayList::new); |
| 111 | + partialFileContent = new PartialFileContent(renderingFailure.getTemplateName(), fileLineList); |
108 | 112 |
|
109 | 113 | if (cause.getCause() != null) { |
110 | 114 | cause = cause.getCause(); |
@@ -115,22 +119,46 @@ public Result onServerError(final Context context, final Throwable throwable) { |
115 | 119 | subHeaderError = stackTraceElement.toString(); |
116 | 120 | lineNumberFromZero = stackTraceElement.getLineNumber() - 1; |
117 | 121 |
|
118 | | - final String javaFileName = stackTraceElement.getClassName().replace(StringConstants.DOT, File.separator).split("\\$", 2)[0] + ".java"; |
119 | | - final Optional<Path> javaFilepathOptional = resolvePossibleJavaFileLocation(javaFileName); |
120 | | - fileLineList = javaFilepathOptional.map(path -> retrievePartialFileContent(path, lineNumberFromZero)).orElseGet(ArrayList::new); |
| 122 | + partialFileContent = extractPartialContentFromFirstAccessibleJavaFile(cause); |
121 | 123 | } |
122 | 124 |
|
123 | 125 | return Result.internalServerError( |
124 | 126 | DevMode500InternalServerError.render( |
125 | 127 | cause.getMessage() != null ? cause.getMessage() : "Oops, something goes wrong", |
126 | 128 | subHeaderError, |
127 | 129 | lineNumberFromZero, |
128 | | - fileLineList)); |
| 130 | + partialFileContent)); |
129 | 131 | } |
130 | 132 |
|
131 | 133 | return Result.internalServerError("500 Internal Server Error"); |
132 | 134 | } |
133 | 135 |
|
| 136 | + /** |
| 137 | + * Extract partial content from the first accessible Java file retrieved from the throwable. |
| 138 | + * |
| 139 | + * @param throwable The throwable to use |
| 140 | + * @return Extracted partial file content |
| 141 | + * @since 1.12.0 |
| 142 | + */ |
| 143 | + private PartialFileContent extractPartialContentFromFirstAccessibleJavaFile(final Throwable throwable) { |
| 144 | + |
| 145 | + for (final StackTraceElement stackTraceElement : throwable.getStackTrace()) { |
| 146 | + final String javaFileName = stackTraceElement.getClassName() |
| 147 | + .replace(StringConstants.DOT, File.separator) |
| 148 | + .split("\\$", 2)[0] + ".java"; |
| 149 | + |
| 150 | + final Optional<Path> pathOptional = resolvePossibleJavaFileLocation(javaFileName); |
| 151 | + if (pathOptional.isPresent()) { |
| 152 | + final List<FileLine> fileLineList = retrievePartialFileContent( |
| 153 | + pathOptional.get(), |
| 154 | + stackTraceElement.getLineNumber() - 1); |
| 155 | + return new PartialFileContent(javaFileName, fileLineList); |
| 156 | + } |
| 157 | + } |
| 158 | + |
| 159 | + return null; |
| 160 | + } |
| 161 | + |
134 | 162 | /** |
135 | 163 | * Resolve possible Java file location. |
136 | 164 | * |
@@ -216,6 +244,16 @@ private List<FileLine> retrievePartialFileContent(final Path javaFilePath, |
216 | 244 | return fileLineList; |
217 | 245 | } |
218 | 246 |
|
| 247 | + /** |
| 248 | + * Represents a partial file content. |
| 249 | + * |
| 250 | + * @param filename The filename |
| 251 | + * @param fileLineList The lines |
| 252 | + * @since 1.12.0 |
| 253 | + */ |
| 254 | + public record PartialFileContent(String filename, List<FileLine> fileLineList) { |
| 255 | + } |
| 256 | + |
219 | 257 | /** |
220 | 258 | * Represents a single content line. |
221 | 259 | * |
|