jooby-project / jooby

The modular web framework for Java and Kotlin
https://jooby.io
Apache License 2.0
1.7k stars 199 forks source link

assets: custom response when asset isn't found #3501

Closed jonaskahn closed 4 weeks ago

jonaskahn commented 1 month ago

I want to make a customized handler to handle 404 error, when error happen, send back 404 page Here is my implementation

package com.sample

import io.jooby.kt.Kooby
import io.jooby.kt.runApp
import io.jooby.netty.NettyServer
import io.jooby.OpenAPIModule
import io.jooby.StatusCode
import io.jooby.handler.AssetHandler
import io.jooby.handler.AssetSource
import java.time.Duration

class App: Kooby({
  install(NettyServer())
  install(OpenAPIModule())
  mvc(Controller())

  val www = AssetSource.create(this.classLoader, "static")
  assets(
    "/*", AssetHandler(www)
      .setMaxAge(Duration.ofDays(365))
  )

  error(StatusCode.NOT_FOUND) { ctx, _, _ ->
    ctx.sendRedirect("/404.html")
  }
})

fun main(args: Array<String>) {
  runApp(args, ::App)
}

I tried with sendRedirect or forward, but it does not work. Could you show me the way to send a html page for 404 error?

jknack commented 1 month ago

Hi

The asset handler by default generates a silent 404 response. Try this:

assets(
    "/*", AssetHandler("404.html", www)
      .setMaxAge(Duration.ofDays(365))
  )

https://jooby.io/#static-files-spas

jonaskahn commented 1 month ago

So, I want to set custom error for 500, 404, 403. Therefore, I seem can not apply this. Btw, I am using SPA page, I change to default fallback to index.html, then it works like what I expected.

jknack commented 1 month ago

Got it. We can change asset handler to throw an exception instead. Meanwhile you can try this:

  1. create your own AssetSource that delegates to another asset source, so when asset is null you throw the error you want so error handler catch and handle it.
jonaskahn commented 1 month ago

Got it. We can change asset handler to throw an exception instead. Meanwhile you can try this:

  1. create your own AssetSource that delegates to another asset source, so when asset is null you throw the error you want so error handler catch and handle it.

I see. I'll try that, thank you.