Repository: withastro/astro
File: packages/astro/src/vite-plugin-astro-server/base.ts (TypeScript)

Code before:
import colors from 'piccolore';
import type * as vite from 'vite';
import type { Logger } from '../core/logger/core.js';
import { notFoundTemplate, subpathNotUsedTemplate } from '../template/4xx.js';
import type { AstroSettings } from '../types/astro.js';
import { writeHtmlResponse } from './response.js';

export function baseMiddleware(
	settings: AstroSettings,
	logger: Logger,
): vite.Connect.NextHandleFunction {
	const { config } = settings;
	let devRoot: string;
	let devRootReplacement: string;
	let devRootURL: URL;
	try {
		const site = config.site ? new URL(config.base, config.site) : undefined;
		devRootURL = new URL(config.base, 'http://localhost');
		devRoot = site ? site.pathname : devRootURL.pathname;
		devRootReplacement = devRoot.endsWith('/') ? '/' : '';
	} catch {
		// If base is invalid, default to '/'
		devRootURL = new URL('/', 'http://localhost');
		devRoot = '/';
		devRootReplacement = '/';
	}

	return function devBaseMiddleware(req, res, next) {
		const url = req.url!;
		let pathname: string;
		try {
			pathname = decodeURI(new URL(url, 'http://localhost').pathname);
		} catch (e) {
			/* malformed uri */
			return next(e);
		}

		if (pathname.startsWith(devRoot)) {
			req.url = url.replace(devRoot, devRootReplacement);
			return next();
		}

		if (pathname === '/' || pathname === '/index.html') {
			const html = subpathNotUsedTemplate(devRoot, pathname);
			return writeHtmlResponse(res, 404, html);
		}

		if (req.headers.accept?.includes('text/html')) {
			const html = notFoundTemplate(pathname);
			return writeHtmlResponse(res, 404, html);
		}

Review comment (suggestion):
Instead of a try/catch, could it be possible to have the previous code but with `config.base || '/'`

Code after:
import colors from 'piccolore';
import type * as vite from 'vite';
import type { Logger } from '../core/logger/core.js';
import { notFoundTemplate, subpathNotUsedTemplate } from '../template/4xx.js';
import type { AstroSettings } from '../types/astro.js';
import { writeHtmlResponse } from './response.js';

export function baseMiddleware(
	settings: AstroSettings,
	logger: Logger,
): vite.Connect.NextHandleFunction {
	const { config } = settings;
	// The base may be an empty string by now, causing the URL creation to fail. We provide a default instead
	const base = config.base || '/';
	const site = config.site ? new URL(base, config.site) : undefined;
	const devRootURL = new URL(base, 'http://localhost');
	const devRoot = site ? site.pathname : devRootURL.pathname;
	const devRootReplacement = devRoot.endsWith('/') ? '/' : '';

	return function devBaseMiddleware(req, res, next) {
		const url = req.url!;
		let pathname: string;
		try {
			pathname = decodeURI(new URL(url, 'http://localhost').pathname);
		} catch (e) {
			/* malformed uri */
			return next(e);
		}

		if (pathname.startsWith(devRoot)) {
			req.url = url.replace(devRoot, devRootReplacement);
			return next();
		}

		if (pathname === '/' || pathname === '/index.html') {
			const html = subpathNotUsedTemplate(devRoot, pathname);
			return writeHtmlResponse(res, 404, html);
		}

		if (req.headers.accept?.includes('text/html')) {
			const html = notFoundTemplate(pathname);
			return writeHtmlResponse(res, 404, html);
		}

		// Check to see if it's in public and if so 404
		const publicPath = new URL('.' + req.url, config.publicDir);
		fs.stat(publicPath, (_err, stats) => {
			if (stats) {
				const publicDir = appendForwardSlash(
					path.posix.relative(config.root.pathname, config.publicDir.pathname),
				);