Hono Sub-App Route Handler Returns Undefined → CF Error 1101
Problem
Un Cloudflare Worker utilisant Hono avec des sub-apps plante avec Error 1101 ("Worker threw
exception") quand un route handler dans une sub-app retourne undefined au lieu d'une Response.
Cela arrive couramment quand les route handlers ont des gardes d'hostname qui utilisent un bare return pour
sauter le traitement, dans l'intention de laisser d'autres routes gérer la requête.
Context / Trigger Conditions
- Le dashboard Cloudflare Workers ou le navigateur affiche Error 1101: Worker threw exception
- Les logs de
wrangler devaffichent : "Incorrect type for Promise: the Promise did not resolve to 'Response'" - Plusieurs hostnames routent vers le même worker (ex.
names.divine.videoetnames.admin.divine.video) - La sub-app Hono a des route handlers avec des vérifications conditionnelles d'hostname qui utilisent bare
return - La sub-app a du middleware qui appelle
next()pour les hostnames non-correspondants, mais les route handlers dupliquent la vérification et retournentundefined
Root Cause
Dans Hono, les route handlers (.get(), .post(), etc.) DOIVENT retourner une Response. Seul
le middleware (enregistré via .use()) peut appeler next() pour passer le contrôle en aval.
Cependant, si un route handler inclut next dans sa liste de paramètres (async (c, next) => {}),
Hono le traite comme du middleware-like, permettant return next() de passer le contrôle au
prochain handler correspondant.
Un bare return (qui retourne undefined) depuis un route handler cause au runtime Cloudflare
Workers de lever une exception car il attend un objet Response.
Solution
Mauvais — retourne undefined, plante le worker :
app.get('/', async (c) => {
if (!ALLOWED_HOSTNAMES.includes(hostname)) {
return // undefined! → Error 1101
}
return c.html(page())
})
Bon — accepte le paramètre next et l'appelle pour passer le contrôle :
app.get('/', async (c, next) => {
if (!ALLOWED_HOSTNAMES.includes(hostname)) {
return next() // passe au handler suivant dans la chaîne
}
return c.html(page())
})
Point clé : Ajouter next à la signature du handler change la façon dont Hono traite le
handler, lui permettant de déléguer aux routes en aval.
Verification
- Exécutez
wrangler devet curl avec l'hostname non-correspondant :curl -s -o /dev/null -w "%{http_code}" http://localhost:8787/ -H "Host: other.example.com" - Devrait retourner un code HTTP valide (200, 404, etc.) au lieu de 500
- Pas d'erreurs "did not resolve to Response" dans le terminal
Example
Un worker sert à la fois names.divine.video (interface publique) et names.admin.divine.video
(SPA admin). La sub-app des routes publiques a un handler de page d'accueil qui répond seulement pour
names.divine.video. Quand names.admin.divine.video atteint ce handler, il devrait passer
au handler catch-all de l'SPA admin. Utiliser bare return plante le worker ;
utiliser return next() (avec next dans les paramètres) délègue correctement.
Notes
- Cela ne s'applique qu'aux route handlers Hono, pas au middleware (les handlers
.use()ont toujoursnext) - L'erreur est invisible dans le dashboard Cloudflare — vous ne voyez que le générique "Error 1101"
wrangler devdonne la vraie erreur : "the Promise did not resolve to 'Response'"- Si votre middleware de sub-app garde déjà les routes, vous n'aurez peut-être pas besoin de vérifications d'hostname dans les handlers individuels — mais si vous en avez, utilisez le pattern
next - Ce pattern est courant dans les workers multi-tenant où un worker gère plusieurs hostnames