Skip to content

Commit a6db6e2

Browse files
authored
Merge pull request #2855: fix(cli) resolve http.server via getServiceAsync (console/runtime-assets)
Merged via merge-commit so the cloud-pinned commit decd174 stays reachable in main history (matches the cb662a5 precedent). Fixes the console/schema-migration boot crash (com.objectstack.runtime-assets: "Service 'http.server' is async - use await").
2 parents 5f43f88 + decd174 commit a6db6e2

2 files changed

Lines changed: 57 additions & 2 deletions

File tree

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
---
2+
'@objectstack/cli': patch
3+
---
4+
5+
fix(cli): resolve `http.server` asynchronously in the console / runtime-assets static plugins
6+
7+
`createConsoleStaticPlugin` and `createRuntimeAssetsPlugin` fetched the
8+
`http.server` service with the **synchronous** `ctx.getService('http.server')`.
9+
When `http.server` is registered as an async factory (the console /
10+
schema-migration boot path), that accessor throws
11+
`Service 'http.server' is async - use await`; because the call sat outside
12+
any try/catch, the throw escaped the plugin's `start()` and rolled back
13+
kernel bootstrap — crashing the CONSOLE/migration boot
14+
(`Plugin startup failed: com.objectstack.runtime-assets`). The runtime
15+
`serve` path, where `http.server` is registered synchronously, was
16+
unaffected, which is why only the control-plane migration boot broke.
17+
18+
Resolve both plugins' `http.server` through a shared `resolveHttpServer`
19+
helper that prefers the async accessor (`getServiceAsync`, which resolves a
20+
sync- or async-registered service) and falls back to the sync one, mirroring
21+
plugin-auth's async `cache` lookup. The helper never throws, so these
22+
optional static-asset plugins skip cleanly when no HTTP server is present
23+
instead of taking down boot.

packages/cli/src/utils/console.ts

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,38 @@ export function warnOnConsoleShaDrift(
328328

329329
// ─── Plugin Factory ─────────────────────────────────────────────────
330330

331+
/**
332+
* Resolve the `http.server` service from a plugin context, tolerating both
333+
* ways it can be registered:
334+
*
335+
* - **synchronously** — the runtime `serve` path, where `Runtime` registers
336+
* the concrete server instance; and
337+
* - as an **async factory** — the console / schema-migration boot path,
338+
* for which the *synchronous* `getService` throws
339+
* `Service 'http.server' is async - use await`. Without this the throw
340+
* escaped these static-asset plugins' `start()` and aborted kernel
341+
* bootstrap (`com.objectstack.runtime-assets` failed to start), taking
342+
* down the CONSOLE/migration boot entirely.
343+
*
344+
* Prefer the async accessor (`getServiceAsync`, which resolves either kind),
345+
* falling back to the sync one — mirroring plugin-auth's async `cache` lookup.
346+
* Never throws: an unavailable server resolves to `undefined`, so these
347+
* optional static-asset plugins skip cleanly instead of crashing boot.
348+
*/
349+
async function resolveHttpServer(ctx: any): Promise<any> {
350+
try {
351+
const svc = await ctx.getServiceAsync?.('http.server');
352+
if (svc) return svc;
353+
} catch {
354+
// fall through to the synchronous accessor
355+
}
356+
try {
357+
return ctx.getService?.('http.server');
358+
} catch {
359+
return undefined;
360+
}
361+
}
362+
331363
/**
332364
* Create a lightweight kernel plugin that serves the pre-built Console
333365
* portal static files at `/_console/*`.
@@ -347,7 +379,7 @@ export function createConsoleStaticPlugin(distPath: string, options?: { isDev?:
347379
init: async () => {},
348380

349381
start: async (ctx: any) => {
350-
const httpServer = ctx.getService?.('http.server');
382+
const httpServer = await resolveHttpServer(ctx);
351383
if (!httpServer?.getRawApp) {
352384
ctx.logger?.warn?.('Console static: http.server service not found — skipping');
353385
return;
@@ -468,7 +500,7 @@ export function createRuntimeAssetsPlugin(distPath: string) {
468500
init: async () => {},
469501

470502
start: async (ctx: any) => {
471-
const httpServer = ctx.getService?.('http.server');
503+
const httpServer = await resolveHttpServer(ctx);
472504
if (!httpServer?.getRawApp) return;
473505

474506
const app = httpServer.getRawApp();

0 commit comments

Comments
 (0)