diff --git a/flash-extensions/flash-ext-openapi/src/main/java/dev/relism/flash/ext/openapi/OpenApiExtension.java b/flash-extensions/flash-ext-openapi/src/main/java/dev/relism/flash/ext/openapi/OpenApiExtension.java index aff5f09..e914e1d 100644 --- a/flash-extensions/flash-ext-openapi/src/main/java/dev/relism/flash/ext/openapi/OpenApiExtension.java +++ b/flash-extensions/flash-ext-openapi/src/main/java/dev/relism/flash/ext/openapi/OpenApiExtension.java @@ -10,6 +10,7 @@ import dev.relism.flash.extension.RouteEvent; import dev.relism.flash.http.ContentType; import dev.relism.flash.http.HttpMethod; import dev.relism.flash.routing.Route; +import lombok.extern.slf4j.Slf4j; /** * Generates and serves an OpenAPI 3.0 spec and Swagger UI under a configurable base path. @@ -34,6 +35,7 @@ import dev.relism.flash.routing.Route; * .start(); * } */ +@Slf4j public class OpenApiExtension implements FlashExtension { private static final String YAML_CONTENT_TYPE = "application/yaml"; @@ -124,7 +126,11 @@ public class OpenApiExtension implements FlashExtension { if (handlerClass == null) return; // lambda route: no annotation metadata ApiOperation op = handlerClass.getAnnotation(ApiOperation.class); - if (op == null) return; + if (op == null) { + log.warn("{} {} ({}) has no @ApiOperation — omitted from the OpenAPI spec", + event.method(), event.path(), handlerClass.getSimpleName()); + return; + } builder.addOperation(routeOf(event), op, handlerClass); } diff --git a/flash/src/main/java/dev/relism/flash/extension/FlashRegistrar.java b/flash/src/main/java/dev/relism/flash/extension/FlashRegistrar.java index bd83f87..188d1c9 100644 --- a/flash/src/main/java/dev/relism/flash/extension/FlashRegistrar.java +++ b/flash/src/main/java/dev/relism/flash/extension/FlashRegistrar.java @@ -51,6 +51,12 @@ public abstract class FlashRegistrar> { public final SELF purge (String path, SimpleHandler.FunctionalHandler h, Middleware... mw) { return route(HttpMethod.PURGE, path, h, mw); } public final SELF query (String path, SimpleHandler.FunctionalHandler h, Middleware... mw) { return route(HttpMethod.QUERY, path, h, mw); } + /** Registers {@code h} under every {@link HttpMethod}: for handlers indifferent to verb (e.g. a proxy). */ + public final SELF any(String path, SimpleHandler.FunctionalHandler h, Middleware... mw) { + for (HttpMethod m : HttpMethod.values()) route(m, path, h, mw); + return (SELF) this; + } + public final SELF getWith (String path, SimpleHandler.FunctionalHandler h, MiddlewareNode... mw) { return route(HttpMethod.GET, path, h, mw); } public final SELF postWith (String path, SimpleHandler.FunctionalHandler h, MiddlewareNode... mw) { return route(HttpMethod.POST, path, h, mw); } public final SELF putWith (String path, SimpleHandler.FunctionalHandler h, MiddlewareNode... mw) { return route(HttpMethod.PUT, path, h, mw); } diff --git a/flash/src/main/java/dev/relism/flash/routing/AbstractRouter.java b/flash/src/main/java/dev/relism/flash/routing/AbstractRouter.java index 4ad7dcb..4473359 100644 --- a/flash/src/main/java/dev/relism/flash/routing/AbstractRouter.java +++ b/flash/src/main/java/dev/relism/flash/routing/AbstractRouter.java @@ -7,6 +7,7 @@ import dev.relism.flash.Flash; import dev.relism.flash.http.ContentType; import dev.relism.flash.http.HttpMethod; import dev.relism.flash.template.ErrorPages; +import lombok.extern.slf4j.Slf4j; import java.nio.charset.StandardCharsets; @@ -29,6 +30,7 @@ import java.nio.charset.StandardCharsets; *

Registration: use {@link FlashApp} — the single * public registration API. {@link #doRegister} is an infrastructure method. */ +@Slf4j public abstract class AbstractRouter { /** Eagerly validates and compiles this route graph before traffic is accepted. */ @@ -59,6 +61,7 @@ public abstract class AbstractRouter { return ErrorPages.renderException(req, ex); } : (ex, req, res) -> { + log.error("Unhandled exception in {} {}", req.method(), req.path(), ex); res.status(500); res.type(ContentType.JSON); return JSON_500;