Skip to content

Commit 09ae9a3

Browse files
committed
Cleanup GrailsWrappedRuntimeException
1 parent e663697 commit 09ae9a3

File tree

1 file changed

+4
-283
lines changed

1 file changed

+4
-283
lines changed

grace-web-mvc/src/main/groovy/org/grails/web/errors/GrailsWrappedRuntimeException.java

Lines changed: 4 additions & 283 deletions
Original file line numberDiff line numberDiff line change
@@ -15,41 +15,12 @@
1515
*/
1616
package org.grails.web.errors;
1717

18-
import java.io.IOException;
19-
import java.io.InputStream;
20-
import java.io.InputStreamReader;
21-
import java.io.LineNumberReader;
22-
import java.lang.reflect.Constructor;
23-
import java.util.regex.Matcher;
24-
import java.util.regex.Pattern;
25-
2618
import jakarta.servlet.ServletContext;
2719

28-
import org.apache.commons.logging.Log;
29-
import org.apache.commons.logging.LogFactory;
30-
import org.codehaus.groovy.control.MultipleCompilationErrorsException;
31-
import org.codehaus.groovy.control.messages.SyntaxErrorMessage;
32-
import org.springframework.core.io.Resource;
33-
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
34-
import org.springframework.util.ClassUtils;
35-
import org.springframework.util.ReflectionUtils;
36-
import org.springframework.web.context.WebApplicationContext;
37-
import org.springframework.web.context.support.WebApplicationContextUtils;
38-
39-
import grails.artefact.ArtefactTypes;
40-
import grails.core.GrailsApplication;
41-
import grails.util.GrailsStringUtils;
42-
43-
import org.grails.buffer.FastStringPrintWriter;
4420
import org.grails.core.exceptions.GrailsException;
45-
import org.grails.exceptions.reporting.SourceCodeAware;
46-
import org.grails.gsp.ResourceAwareTemplateEngine;
47-
import org.grails.io.support.GrailsFactoriesLoader;
48-
import org.grails.web.servlet.mvc.GrailsWebRequest;
49-
import org.grails.web.util.GrailsApplicationAttributes;
5021

5122
/**
52-
* Wraps a Grails RuntimeException and attempts to extract more relevent diagnostic messages
23+
* Wraps a Grails RuntimeException and attempts to extract more relevant diagnostic messages
5324
* from the stack trace.
5425
*
5526
* @author Graeme Rocher
@@ -58,274 +29,24 @@
5829
*/
5930
public class GrailsWrappedRuntimeException extends GrailsException {
6031

61-
public static final String URL_PREFIX = "/WEB-INF/grails-app/";
62-
63-
private static final Log logger = LogFactory.getLog(GrailsWrappedRuntimeException.class);
64-
65-
private static final Class<? extends GrailsApplicationAttributes> grailsApplicationAttributesClass = GrailsFactoriesLoader.loadFactoryClasses(
66-
GrailsApplicationAttributes.class, GrailsWebRequest.class.getClassLoader()).get(0);
67-
68-
private static final Constructor<? extends GrailsApplicationAttributes> grailsApplicationAttributesConstructor =
69-
ClassUtils.getConstructorIfAvailable(grailsApplicationAttributesClass, ServletContext.class);
70-
7132
private static final long serialVersionUID = 7284065617154554366L;
7233

73-
private static final Pattern ANY_GSP_DETAILS = Pattern.compile("_gsp.run");
74-
75-
private static final Pattern PARSE_DETAILS_STEP1 = Pattern.compile("\\((\\w+)\\.groovy:(\\d+)\\)");
76-
77-
private static final Pattern PARSE_DETAILS_STEP2 = Pattern.compile("at\\s{1}(\\w+)\\$_closure\\d+\\.doCall\\(\\1:(\\d+)\\)");
78-
79-
private static final Pattern PARSE_GSP_DETAILS_STEP1 = Pattern.compile("_gsp\\.run\\(((\\w+?)_.*?):(\\d+)\\)");
80-
81-
private final PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
82-
83-
private static final String UNKNOWN = "Unknown";
84-
85-
private String className = UNKNOWN;
86-
87-
private int lineNumber = -1;
88-
8934
private final Throwable cause;
9035

91-
private final String stackTrace;
92-
93-
private final String[] stackTraceLines;
94-
95-
private String[] codeSnippet = new String[0];
96-
97-
private String gspFile;
98-
99-
private String fileName;
100-
10136
/**
10237
* @param servletContext The ServletContext instance
10338
* @param t The exception that was thrown
10439
*/
10540
public GrailsWrappedRuntimeException(ServletContext servletContext, Throwable t) {
10641
super(t.getMessage(), t);
10742
this.cause = t;
108-
Throwable cause = t;
109-
110-
FastStringPrintWriter pw = FastStringPrintWriter.newInstance();
111-
cause.printStackTrace(pw);
112-
this.stackTrace = pw.toString();
113-
114-
while (cause.getCause() != cause) {
115-
if (cause.getCause() == null) {
116-
break;
117-
}
118-
cause = cause.getCause();
119-
}
120-
121-
this.stackTraceLines = this.stackTrace.split("\\n");
122-
123-
if (cause instanceof MultipleCompilationErrorsException) {
124-
MultipleCompilationErrorsException mcee = (MultipleCompilationErrorsException) cause;
125-
Object message = mcee.getErrorCollector().getErrors().iterator().next();
126-
if (message instanceof SyntaxErrorMessage) {
127-
SyntaxErrorMessage sem = (SyntaxErrorMessage) message;
128-
this.lineNumber = sem.getCause().getLine();
129-
this.className = sem.getCause().getSourceLocator();
130-
sem.write(pw);
131-
}
132-
}
133-
else {
134-
Matcher m1 = PARSE_DETAILS_STEP1.matcher(this.stackTrace);
135-
Matcher m2 = PARSE_DETAILS_STEP2.matcher(this.stackTrace);
136-
Matcher gsp = PARSE_GSP_DETAILS_STEP1.matcher(this.stackTrace);
137-
try {
138-
if (ANY_GSP_DETAILS.matcher(this.stackTrace).find() && gsp.find()) {
139-
System.out.println(gsp.group(1) + " " + gsp.group(2) + " " + gsp.group(3));
140-
this.className = gsp.group(1);
141-
this.lineNumber = Integer.parseInt(gsp.group(3));
142-
this.gspFile = URL_PREFIX + "views/" + gsp.group(2) + '/' + this.className;
143-
}
144-
else {
145-
if (m1.find()) {
146-
do {
147-
this.className = m1.group(1);
148-
this.lineNumber = Integer.parseInt(m1.group(2));
149-
}
150-
while (m1.find());
151-
}
152-
else {
153-
while (m2.find()) {
154-
this.className = m2.group(1);
155-
this.lineNumber = Integer.parseInt(m2.group(2));
156-
}
157-
}
158-
}
159-
}
160-
catch (NumberFormatException ignored) {
161-
}
162-
}
163-
164-
LineNumberReader reader = null;
165-
try {
166-
checkIfSourceCodeAware(t);
167-
checkIfSourceCodeAware(cause);
168-
169-
if (getLineNumber() > -1) {
170-
String fileLocation;
171-
String url = null;
172-
173-
if (this.fileName != null) {
174-
fileLocation = this.fileName;
175-
}
176-
else {
177-
String urlPrefix = "";
178-
if (this.gspFile == null) {
179-
this.fileName = this.className.replace('.', '/') + ".groovy";
180-
181-
GrailsApplication application = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext)
182-
.getBean(GrailsApplication.APPLICATION_ID, GrailsApplication.class);
183-
// @todo Refactor this to get the urlPrefix from the ArtefactHandler
184-
if (application.isArtefactOfType(ArtefactTypes.CONTROLLER, this.className)) {
185-
urlPrefix += "/controllers/";
186-
}
187-
else if (application.isArtefactOfType("TagLib", this.className)) {
188-
urlPrefix += "/taglib/";
189-
}
190-
else if (application.isArtefactOfType(ArtefactTypes.SERVICE, this.className)) {
191-
urlPrefix += "/services/";
192-
}
193-
url = URL_PREFIX + urlPrefix + this.fileName;
194-
}
195-
else {
196-
url = this.gspFile;
197-
try {
198-
WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
199-
if (webApplicationContext != null) {
200-
ResourceAwareTemplateEngine engine =
201-
webApplicationContext.getBean(ResourceAwareTemplateEngine.BEAN_ID, ResourceAwareTemplateEngine.class);
202-
this.lineNumber = engine.mapStackLineNumber(url, this.lineNumber);
203-
}
204-
}
205-
catch (Exception e) {
206-
ReflectionUtils.rethrowRuntimeException(e);
207-
}
208-
}
209-
fileLocation = "grails-app" + urlPrefix + this.fileName;
210-
}
211-
212-
InputStream in = null;
213-
if (!GrailsStringUtils.isBlank(url)) {
214-
in = servletContext.getResourceAsStream(url);
215-
logger.debug("Attempting to display code snippet found in url " + url);
216-
}
217-
if (in == null) {
218-
Resource r = null;
219-
try {
220-
r = this.resolver.getResource(fileLocation);
221-
in = r.getInputStream();
222-
}
223-
catch (Throwable e) {
224-
r = this.resolver.getResource("file:" + fileLocation);
225-
if (r.exists()) {
226-
try {
227-
in = r.getInputStream();
228-
}
229-
catch (IOException ignored) {
230-
}
231-
}
232-
}
233-
}
234-
235-
if (in != null) {
236-
reader = new LineNumberReader(new InputStreamReader(in, "UTF-8"));
237-
String currentLine = reader.readLine();
238-
StringBuilder buf = new StringBuilder();
239-
while (currentLine != null) {
240-
int currentLineNumber = reader.getLineNumber();
241-
if ((this.lineNumber > 0 && currentLineNumber == this.lineNumber - 1) ||
242-
(currentLineNumber == this.lineNumber)) {
243-
buf.append(currentLineNumber)
244-
.append(": ")
245-
.append(currentLine)
246-
.append("\n");
247-
}
248-
else if (currentLineNumber == this.lineNumber + 1) {
249-
buf.append(currentLineNumber)
250-
.append(": ")
251-
.append(currentLine);
252-
break;
253-
}
254-
currentLine = reader.readLine();
255-
}
256-
this.codeSnippet = buf.toString().split("\n");
257-
}
258-
}
259-
}
260-
catch (IOException e) {
261-
logger.warn("[GrailsWrappedRuntimeException] I/O error reading line diagnostics: " + e.getMessage(), e);
262-
}
263-
finally {
264-
if (reader != null) {
265-
try {
266-
reader.close();
267-
}
268-
catch (IOException ignored) {
269-
}
270-
}
271-
}
272-
}
273-
274-
private void checkIfSourceCodeAware(Throwable t) {
275-
if (!(t instanceof SourceCodeAware)) {
276-
return;
277-
}
278-
279-
SourceCodeAware codeAware = (SourceCodeAware) t;
280-
if (codeAware.getFileName() != null) {
281-
this.fileName = codeAware.getFileName();
282-
if (this.className == null || UNKNOWN.equals(this.className)) {
283-
this.className = codeAware.getFileName();
284-
}
285-
}
286-
if (codeAware.getLineNumber() > -1) {
287-
this.lineNumber = codeAware.getLineNumber();
288-
}
289-
}
290-
291-
/**
292-
* @return Returns the line.
293-
*/
294-
public String[] getCodeSnippet() {
295-
return this.codeSnippet;
296-
}
297-
298-
/**
299-
* @return Returns the className.
300-
*/
301-
public String getClassName() {
302-
return this.className;
30343
}
30444

305-
/**
306-
* @return Returns the lineNumber.
307-
*/
308-
public int getLineNumber() {
309-
return this.lineNumber;
310-
}
311-
312-
/**
313-
* @return Returns the stackTrace.
314-
*/
315-
public String getStackTraceText() {
316-
return this.stackTrace;
317-
}
318-
319-
/**
320-
* @return Returns the stackTrace lines
321-
*/
322-
public String[] getStackTraceLines() {
323-
return this.stackTraceLines;
45+
@Override
46+
public Throwable getCause() {
47+
return this.cause;
32448
}
32549

326-
/* (non-Javadoc)
327-
* @see groovy.lang.GroovyRuntimeException#getMessage()
328-
*/
32950
@Override
33051
public String getMessage() {
33152
return this.cause.getMessage();

0 commit comments

Comments
 (0)