Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 41 additions & 11 deletions apps/client/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,20 +83,50 @@ const server = Bun.serve({
}
},
"/manifest": async () => {
await updateManifest(dir);
return Response.json(MANIFEST, {
headers,
});
try {
await updateManifest(dir);
return Response.json(MANIFEST, {
headers,
});
} catch (error) {
console.error("Failed to load manifest:", error);
return Response.json(
{ error: "Failed to load manifest", details: String(error) },
{ status: 500, headers },
);
}
},
"/env": () => {
return Response.json(getGameEnv(), { headers });
try {
const env = getGameEnv();
return Response.json({ ...env, tlsEnabled: !!tls }, { headers });
} catch (error) {
console.error("Failed to load environment:", error);
return Response.json(
{ error: "Failed to load environment", details: String(error) },
{ status: 500, headers },
);
}
},
"/game/*": (req) => {
const path = new URL(req.url).pathname.replace("/game", "");
const file = Bun.file(join(dir, path));
return new Response(file, {
headers,
});
"/game/*": async (req) => {
try {
const path = new URL(req.url).pathname.replace("/game", "");
const file = Bun.file(join(dir, path));

if (!(await file.exists())) {
return Response.json({ error: "Game file not found", path }, { status: 404, headers });
Comment thread
josephinecr marked this conversation as resolved.
}

return new Response(file, {
headers,
});
} catch (error) {
console.error(`Error reading game file ${req.url}:`, error);
return Response.json(
{ error: "Error reading game file", details: String(error) },
{ status: 500, headers },
);
}
},
},
});
Expand Down
16 changes: 16 additions & 0 deletions apps/website/src/cache/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,22 @@ export class GameCache {
private async _updateCacheFile(fileManifest: IManifestFile): Promise<IExtendedManifestFile> {
const res = await fetch(`/game/${fileManifest.path.replace(/^\/+/, "")}`);

if (!res.ok) {
let errorMessage: string;
try {
const errorData = await res.json();

if (errorData.path) {
errorMessage = `${errorData.error} : ${errorData.path}`;
} else {
errorMessage = errorData.error || `HTTP Error ${res.status}`;
}
} catch {
errorMessage = `HTTP Error ${res.status} on file ${fileManifest.path}`;
}
throw new Error(errorMessage);
}

const file = await this.fs.getFile(fileManifest.path);

const writable = await file.getWritable();
Expand Down
15 changes: 15 additions & 0 deletions apps/website/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ const logger = new Logger("Loader");

const runLoad = async () => {
logger.info("Starting loading game");
if (!window.isSecureContext) {
throw new Error(
"Storage issue: The game must be hosted with SSL (HTTPS) to enable local storage and load properly.",
);
}

const manifest = await getManifest();
runWatcher(manifest.watch);
Expand All @@ -22,6 +27,16 @@ const runLoad = async () => {
runGame(mainModule, { files, env });
};

window.addEventListener("error", (event) => {
setError(event.error || event.message);
logger.error(`Runtime error : ${event.message}`);
});

window.addEventListener("unhandledrejection", (event) => {
setError(event.reason);
logger.error(`Unhandled promise rejection : ${event.reason}`);
});

runLoad()
.then(() => {
logger.info("Game loaded !");
Expand Down
8 changes: 6 additions & 2 deletions apps/website/src/window.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,15 @@ export const setLoadingTotalFiles = (total: number) => {
totalFiles = total;
};

export const setError = (error: string) => {
export const setError = (error: string | Error | unknown) => {
const loaderErrorMessage = document.getElementById(IDS.loaderErrorMessage);

if (!loaderErrorMessage) return;
loaderErrorMessage.innerText = error;
const errorMessage = error instanceof Error ? error.message : String(error);
loaderErrorMessage.innerText = errorMessage;

setHiddenStatusOnId(IDS.container, true);
setHiddenStatusOnId(IDS.loader, false);

setHiddenStatusOnId(IDS.loadingStatus, true);
setHiddenStatusOnId(IDS.loaderError, false);
Expand Down
Loading