1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
package no.eliashaugsbakk.clams.server;
import com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException;
import io.javalin.Javalin;
import io.javalin.rendering.template.JavalinPebble;
import java.util.Map;
import no.eliashaugsbakk.clams.server.config.AppContext;
import no.eliashaugsbakk.clams.server.config.AppRoutes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class App {
private static final Logger log = LoggerFactory.getLogger(App.class);
void main() {
// Initialize dependencies
AppContext context = new AppContext();
try {
Javalin.create(config -> {
config.staticFiles.add(staticFiles -> {
staticFiles.hostedPath = "/";
staticFiles.directory = "/public";
});
config.fileRenderer(new JavalinPebble());
config.routes.error(404, ctx -> {
if (ctx.path().startsWith("/api")) {
ctx.json(Map.of(
"error", "Not Found",
"message", "The requested API endpoint does not exist."
));
} else {
ctx.render("templates/404.html", Map.of(
"page_title", "404 - Page Not Found",
"page_css", "404"
));
}
});
config.routes.exception(UnrecognizedPropertyException.class, (e, ctx) -> ctx.status(400).json(Map.of(
"error", "Bad Request",
"message", "Unrecognized property: '" + e.getPropertyName() + "'"
)));
config.routes.exception(Exception.class, (e, ctx) -> {
log.error("Unhandled error on {} {}", ctx.method(), ctx.path(), e);
ctx.status(500);
if (ctx.path().startsWith("/api")) {
ctx.json(Map.of("error", "Internal Server Error"));
} else {
ctx.result("Internal Server Error. Please try again later.");
}
});
config.routes.apiBuilder(new AppRoutes(context));
config.events.serverStopped(context::close);
}).start(7070);
} catch (Exception e) {
context.close();
log.error("Unexpected error", e);
throw e;
}
}
}
|