fix: various fixes to sentry-reported errors and more

This commit is contained in:
Hampus Kraft
2026-02-18 15:38:51 +00:00
parent 302c0d2a0c
commit 0517a966a3
357 changed files with 25420 additions and 16281 deletions

View File

@@ -169,20 +169,21 @@ export function DownloadController(routes: Hono<HonoEnv>): void {
operationId: 'download_file',
summary: 'Download file',
responseSchema: null,
statusCode: 200,
statusCode: 302,
security: [],
tags: ['Downloads'],
description: 'Downloads files from the download service with support for range requests and caching.',
description: 'Redirects to a presigned URL for the requested file.',
}),
async (ctx) => {
const response = await ctx.get('downloadService').streamDownload({
const url = await ctx.get('downloadService').resolveDownloadRedirect({
path: ctx.req.path,
rangeHeader: ctx.req.header('range'),
});
if (!response) {
if (!url) {
return ctx.text('Not Found', 404);
}
return response;
const res = ctx.redirect(url, 302);
res.headers.set('Cache-Control', 'public, max-age=300');
return res;
},
);
}

View File

@@ -415,7 +415,7 @@ export class DownloadService {
return null;
}
async streamDownload(params: {path: string; rangeHeader?: string | null}): Promise<Response | null> {
async resolveDownloadRedirect(params: {path: string}): Promise<string | null> {
const key = this.buildKeyFromPath(params.path);
if (!key) {
return null;
@@ -429,20 +429,13 @@ export class DownloadService {
for (const candidateKey of keysToTry) {
try {
const streamResult = await this.storageService.streamObject({
bucket: Config.s3.buckets.downloads,
key: candidateKey,
range: params.rangeHeader ?? undefined,
});
if (!streamResult) {
continue;
const metadata = await this.storageService.getObjectMetadata(Config.s3.buckets.downloads, candidateKey);
if (metadata) {
return this.storageService.getPresignedDownloadURL({
bucket: Config.s3.buckets.downloads,
key: candidateKey,
});
}
const headers = this.buildDownloadHeaders(streamResult);
const status = streamResult.contentRange ? 206 : 200;
const body = Readable.toWeb(streamResult.body);
return new Response(body as ReadableStream, {headers, status});
} catch (error) {
if (error instanceof S3ServiceException && (error.name === 'NoSuchKey' || error.name === 'NotFound')) {
continue;
@@ -681,26 +674,4 @@ export class DownloadService {
const [, prefix, , , arch, suffix] = match;
return `${prefix}/${arch}${suffix}`;
}
private buildDownloadHeaders(metadata: {
contentLength: number;
contentType?: string | null;
contentRange?: string | null;
}): Headers {
const headers = new Headers();
if (metadata.contentType) {
headers.set('Content-Type', metadata.contentType);
} else {
headers.set('Content-Type', 'application/octet-stream');
}
headers.set('Content-Length', metadata.contentLength.toString());
if (metadata.contentRange) {
headers.set('Content-Range', metadata.contentRange);
headers.set('Accept-Ranges', 'bytes');
} else {
headers.set('Accept-Ranges', 'bytes');
}
headers.set('Cache-Control', 'public, max-age=86400');
return headers;
}
}