Skip to content

Commit ce65074

Browse files
committed
fix: Improve index.html missing error handling and fix ESLint config
When index.html is not found during SPA fallback, the code now returns a proper 500 server error with a clear message instead of a misleading 404. This correctly indicates a build/deployment error rather than a user request error. Also fixes pre-existing ESLint configuration issues: - Configured separate TypeScript project configs for backend and frontend code to resolve parsing errors in src/webui/static files - Added test files to tsconfig.json include array - Replaced conditional require() with proper ES6 top-level import for Windows readline handling Changes: - WebUIManager: Return AppError with ErrorCode.CONFIG_INVALID when index.html is missing, including contextual debugging information - WebUIManager: Added defensive documentation explaining why path.extname() check is safe (app doesn't use client-side routing) - eslint.config.mjs: Split configuration for backend (CommonJS) and frontend (ES modules) with appropriate tsconfig references - tsconfig.json: Added test files to include array - index.ts: Replaced conditional require('readline') with top-level import Fixes #10 comment #3 (Gemini Code Assist review)
1 parent 195e85a commit ce65074

4 files changed

Lines changed: 47 additions & 6 deletions

File tree

eslint.config.mjs

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,19 @@ import globals from 'globals';
66
export default tseslint.config(
77
eslint.configs.recommended,
88
...tseslint.configs.recommended,
9+
10+
// Backend configuration - uses main tsconfig.json
911
{
10-
files: ['**/*.ts', '**/*.tsx'],
12+
files: ['src/**/*.ts', '**/*.ts'],
13+
ignores: [
14+
'src/webui/static/**/*.ts',
15+
'dist/**',
16+
'node_modules/**',
17+
'.dependencies/**'
18+
],
1119
languageOptions: {
1220
ecmaVersion: 2022,
13-
sourceType: 'module',
21+
sourceType: 'commonjs',
1422
globals: {
1523
...globals.node,
1624
},
@@ -29,7 +37,29 @@ export default tseslint.config(
2937
],
3038
},
3139
},
40+
41+
// Frontend configuration - uses webui static tsconfig
3242
{
33-
ignores: ['dist/**', 'node_modules/**', '.dependencies/**'],
43+
files: ['src/webui/static/**/*.ts'],
44+
languageOptions: {
45+
ecmaVersion: 2020,
46+
sourceType: 'module',
47+
globals: {
48+
...globals.browser,
49+
},
50+
parserOptions: {
51+
project: './src/webui/static/tsconfig.json',
52+
},
53+
},
54+
rules: {
55+
'@typescript-eslint/no-explicit-any': 'warn',
56+
'@typescript-eslint/no-unused-vars': [
57+
'error',
58+
{
59+
argsIgnorePattern: '^_',
60+
varsIgnorePattern: '^_',
61+
},
62+
],
63+
},
3464
}
3565
);

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import { getRtspStreamService } from './services/RtspStreamService';
2828
import { initializeSpoolmanIntegrationService } from './services/SpoolmanIntegrationService';
2929
import { getSavedPrinterService } from './services/SavedPrinterService';
3030
import { parseHeadlessArguments, validateHeadlessConfig } from './utils/HeadlessArguments';
31+
import * as readline from 'readline';
3132
import { withTimeout, createHardDeadline } from './utils/ShutdownTimeout';
3233
import type { HeadlessConfig, PrinterSpec } from './utils/HeadlessArguments';
3334
import type { PrinterDetails, PrinterClientType } from './types/printer';
@@ -294,7 +295,6 @@ function setupSignalHandlers(): void {
294295

295296
// Windows-specific: Handle process termination
296297
if (process.platform === 'win32') {
297-
const readline = require('readline');
298298
const rl = readline.createInterface({
299299
input: process.stdin,
300300
output: process.stdout

src/webui/server/WebUIManager.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,10 @@ export class WebUIManager extends EventEmitter {
232232

233233
// SPA fallback - serve index.html for non-API routes that don't match static files
234234
// This enables client-side routing in the WebUI
235+
236+
// NOTE: Using path.extname() is safe here because this app does NOT use client-side routing.
237+
// All UI state is managed via DOM manipulation, not URL routes. If client-side routing
238+
// is added in the future, this should be changed to use Accept header detection instead.
235239
this.expressApp.get('/*splat', (req, res, next) => {
236240
// Skip if this looks like a file request with extension (handled by static middleware)
237241
if (path.extname(req.path) && req.path !== '/') {
@@ -249,7 +253,12 @@ export class WebUIManager extends EventEmitter {
249253
if (fs.existsSync(indexPath)) {
250254
res.sendFile(indexPath);
251255
} else {
252-
next();
256+
// index.html is missing - this indicates a build/deployment error
257+
next(new AppError(
258+
'WebUI application files not found. Please ensure the application has been built properly.',
259+
ErrorCode.CONFIG_INVALID,
260+
{ indexPath, staticPath: this.webUIStaticPath }
261+
));
253262
}
254263
});
255264

tsconfig.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@
2828
"src/services/**/*.ts",
2929
"src/types/**/*.ts",
3030
"src/utils/**/*.ts",
31-
"src/webui/**/*.ts"
31+
"src/webui/**/*.ts",
32+
"src/__tests__/**/*.ts",
33+
"**/*.test.ts"
3234
],
3335
"exclude": [
3436
"node_modules",

0 commit comments

Comments
 (0)