Skip to content

Commit e6f4907

Browse files
committed
developer friendly error page
1 parent b3ccfe6 commit e6f4907

28 files changed

Lines changed: 472 additions & 38 deletions

src/main/java/act/app/App.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import act.util.ClassInfoByteCodeScanner;
2121
import act.util.ClassInfoSourceCodeScanner;
2222
import act.util.UploadFileStorageService;
23+
import act.view.ActServerError;
2324
import org.apache.commons.codec.Charsets;
2425
import org.osgl._;
2526
import org.osgl.exception.UnexpectedException;
@@ -68,6 +69,8 @@ public enum F {
6869
private DependencyInjector<?> dependencyInjector;
6970
private IStorageService uploadFileStorageService;
7071
private ServiceResourceManager serviceResourceManager;
72+
// used in dev mode only
73+
private CompilationException compilationException;
7174

7275
protected App() {
7376
}
@@ -115,6 +118,9 @@ public ProjectLayout layout() {
115118

116119
public void detectChanges() {
117120
classLoader.detectChanges();
121+
if (null != compilationException) {
122+
throw new ActServerError(compilationException, this);
123+
}
118124
}
119125

120126
public void restart() {
@@ -143,7 +149,13 @@ public void refresh() {
143149
eventManager().emitEvent(PRE_LOAD_CLASSES);
144150
eventBus().emit(PRE_LOAD_CLASSES);
145151
initClassLoader();
146-
scanAppCodes();
152+
try {
153+
scanAppCodes();
154+
compilationException = null;
155+
} catch (CompilationException e) {
156+
compilationException = e;
157+
throw new ActServerError(e, this);
158+
}
147159
eventBus().emit(APP_CODE_SCANNED);
148160
loadRoutes();
149161
// setting context class loader here might lead to memory leaks

src/main/java/act/app/AppCompiler.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import act.conf.AppConfig;
44
import act.util.DestroyableBase;
5+
import act.view.ActServerError;
56
import org.eclipse.jdt.core.compiler.IProblem;
67
import org.eclipse.jdt.internal.compiler.*;
78
import org.eclipse.jdt.internal.compiler.Compiler;
@@ -176,7 +177,12 @@ public void acceptResult(CompilationResult result) {
176177
// If error
177178
if (result.hasErrors()) {
178179
for (IProblem problem : result.getErrors()) {
179-
String className = new String(problem.getOriginatingFileName()).replace("/", ".");
180+
char[][] caa = result.packageName;
181+
StringBuilder sb = S.builder();
182+
for (char[] ca: caa) {
183+
sb.append(ca).append(".");
184+
}
185+
String className = sb.append(new String(problem.getOriginatingFileName())).toString();
180186
className = className.substring(0, className.length() - 5);
181187
String message = problem.getMessage();
182188
if (problem.getID() == IProblem.CannotImportPackage) {

src/main/java/act/app/AppContext.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import act.conf.AppConfig;
66
import act.data.MapUtil;
77
import act.data.RequestBodyParser;
8+
import act.handler.RequestHandler;
9+
import act.route.Router;
810
import act.view.Template;
911
import org.osgl._;
1012
import org.osgl.concurrent.ContextLocal;
@@ -45,6 +47,8 @@ public class AppContext implements ParamValueProvider, Destroyable {
4547
private Map<String, Object> controllerInstances;
4648
private List<ISObject> uploads;
4749
private Set<ConstraintViolation> violations;
50+
private Router router;
51+
private RequestHandler handler;
4852

4953
private AppContext(App app, H.Request request, H.Response response) {
5054
E.NPE(app, request, response);
@@ -87,6 +91,26 @@ public H.Flash flash() {
8791
return flash;
8892
}
8993

94+
public Router router() {
95+
return router;
96+
}
97+
98+
public AppContext router(Router router) {
99+
E.NPE(router);
100+
this.router = router;
101+
return this;
102+
}
103+
104+
public RequestHandler handler() {
105+
return handler;
106+
}
107+
108+
public AppContext handler(RequestHandler handler) {
109+
E.NPE(handler);
110+
this.handler = handler;
111+
return this;
112+
}
113+
90114
public H.Format accept() {
91115
return req().accept();
92116
}
@@ -382,6 +406,8 @@ public void destroy() {
382406
this.renderArgs.clear();
383407
this.attributes.clear();
384408
this.template = null;
409+
this.router = null;
410+
this.handler = null;
385411
this.app = null;
386412
// xio impl might need this this.request = null;
387413
// xio impl might need this this.response = null;
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package act.app;
2+
3+
import org.osgl.util.C;
4+
import org.osgl.util.E;
5+
6+
import java.util.List;
7+
8+
public class SourceInfoImpl implements SourceInfo {
9+
10+
private Source source;
11+
private int line;
12+
public SourceInfoImpl(Source source, int line) {
13+
E.NPE(source);
14+
this.source = source;
15+
this.line = line;
16+
}
17+
18+
@Override
19+
public String fileName() {
20+
return source.file().getName();
21+
}
22+
23+
@Override
24+
public List<String> lines() {
25+
return C.listOf(source.code().split("\n"));
26+
}
27+
28+
@Override
29+
public Integer lineNumber() {
30+
return line;
31+
}
32+
33+
@Override
34+
public boolean isSourceAvailable() {
35+
return true;
36+
}
37+
}

src/main/java/act/boot/spark/SparkApp.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import act.handler.builtin.Redirect;
1414
import act.handler.builtin.StaticFileGetter;
1515
import act.route.Router;
16+
import act.view.ActServerError;
1617
import act.xio.NetworkClient;
1718
import act.xio.NetworkService;
1819
import act.xio.undertow.UndertowService;
@@ -257,7 +258,7 @@ public void handle(AppContext context) {
257258
result = r;
258259
} catch (RuntimeException e) {
259260
logger.error(e, "Error handling request: %s", e.getMessage());
260-
result = Controller.Util.serverError(e);
261+
result = new ActServerError(e, app);
261262
}
262263
}
263264

src/main/java/act/controller/Controller.java

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import act.app.AppContext;
44
import act.conf.AppConfigKey;
5+
import act.view.ActServerError;
56
import act.view.RenderAny;
67
import act.view.RenderTemplate;
78
import org.osgl.http.H;
@@ -184,27 +185,6 @@ public static Forbidden forbidden(String msg, Object... args) {
184185
return null == msg ? FORBIDDEN : new Forbidden(msg, args);
185186
}
186187

187-
/**
188-
* Returns a {@link ServerError} with caused exception
189-
* @param e the exception caused the server error
190-
*/
191-
public static ServerError serverError(Exception e) {
192-
return new ServerError(e);
193-
}
194-
195-
/**
196-
* Returns a {@link ServerError} with caused exception and the
197-
* customized error message template and arguments. The final message
198-
* is rendered with the template and arguments using
199-
* {@link String#format(String, Object...)}
200-
* @param e
201-
* @param message
202-
* @param args
203-
*/
204-
public static ServerError serverError(Exception e, String message, Object ... args) {
205-
return new ServerError(e, message, args);
206-
}
207-
208188
public static Redirect redirect(String url, Object ... args) {
209189
return new Redirect(url, args);
210190
}

src/main/java/act/handler/DelegateRequestHandler.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,9 @@ public RequestHandlerBase realHandler() {
4141
protected void releaseResources() {
4242
handler_.destroy();
4343
}
44+
45+
@Override
46+
public String toString() {
47+
return handler().toString();
48+
}
4449
}

src/main/java/act/handler/builtin/AlwaysBadRequest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,9 @@ public class AlwaysBadRequest extends FastRequestHandler {
1212
public void handle(AppContext context) {
1313
BadRequest.INSTANCE.apply(context.req(), context.resp());
1414
}
15+
16+
@Override
17+
public String toString() {
18+
return "error: bad request";
19+
}
1520
}

src/main/java/act/handler/builtin/AlwaysForbidden.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,9 @@ public class AlwaysForbidden extends FastRequestHandler {
1212
public void handle(AppContext context) {
1313
Forbidden.INSTANCE.apply(context.req(), context.resp());
1414
}
15+
16+
@Override
17+
public String toString() {
18+
return "error: forbidden";
19+
}
1520
}

src/main/java/act/handler/builtin/AlwaysNotFound.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,9 @@ public class AlwaysNotFound extends FastRequestHandler {
1212
public void handle(AppContext context) {
1313
NotFound.INSTANCE.apply(context.req(), context.resp());
1414
}
15+
16+
@Override
17+
public String toString() {
18+
return "error: not found";
19+
}
1520
}

0 commit comments

Comments
 (0)