fix: 修正Blog Live2D缺失资源状态码
This commit is contained in:
parent
453d95ef35
commit
2a30049600
@ -1,4 +1,8 @@
|
||||
import { BadRequestException, Injectable } from '@nestjs/common';
|
||||
import {
|
||||
BadRequestException,
|
||||
Injectable,
|
||||
NotFoundException,
|
||||
} from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { MinioClientService } from './asset-minio.service';
|
||||
import type {
|
||||
@ -11,6 +15,24 @@ const DEFAULT_LIVE2D_BUCKET = 'kt-template-online';
|
||||
const DEFAULT_LIVE2D_PREFIX = 'blog/live2d/pio';
|
||||
const MAX_DECODE_DEPTH = 6;
|
||||
|
||||
/**
|
||||
* Detects MinIO/S3 object-missing errors from `statObject` and `getObject`.
|
||||
* @param error - Unknown failure thrown by the MinIO client while resolving a runtime object.
|
||||
* @returns `true` when the failure means the requested object key does not exist.
|
||||
*/
|
||||
function isMinioObjectNotFound(error: unknown): boolean {
|
||||
if (!error || typeof error !== 'object') {
|
||||
return false;
|
||||
}
|
||||
|
||||
const candidate = error as { code?: unknown; message?: unknown };
|
||||
return (
|
||||
candidate.code === 'NotFound' ||
|
||||
candidate.code === 'NoSuchKey' ||
|
||||
candidate.message === 'Not Found'
|
||||
);
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class BlogLive2DAssetService {
|
||||
/**
|
||||
@ -54,10 +76,17 @@ export class BlogLive2DAssetService {
|
||||
version: string,
|
||||
objectPath: BlogLive2DRuntimeAssetPath,
|
||||
): Promise<BlogLive2DAssetResult> {
|
||||
return this.minioClientService.getObject(
|
||||
try {
|
||||
return await this.minioClientService.getObject(
|
||||
this.resolveRuntimeObjectPath(version, objectPath),
|
||||
this.getBucketName(),
|
||||
);
|
||||
} catch (error) {
|
||||
if (isMinioObjectNotFound(error)) {
|
||||
throw new NotFoundException('Live2D runtime asset not found');
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -117,6 +117,28 @@ describe('BlogLive2DAssetService', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('maps missing MinIO runtime objects to HTTP 404', async () => {
|
||||
const minio = createMinio();
|
||||
minio.getObject.mockRejectedValueOnce(
|
||||
Object.assign(new Error('Not Found'), { code: 'NotFound' }),
|
||||
);
|
||||
const service = new BlogLive2DAssetService(
|
||||
minio as never,
|
||||
createConfig() as never,
|
||||
);
|
||||
|
||||
await expect(
|
||||
service.getRuntimeObject('v1', ['manifest.json']),
|
||||
).rejects.toMatchObject({
|
||||
status: HttpStatus.NOT_FOUND,
|
||||
message: 'Live2D runtime asset not found',
|
||||
});
|
||||
expect(minio.getObject).toHaveBeenCalledWith(
|
||||
'blog/live2d/pio/v1/manifest.json',
|
||||
'kt-template-online',
|
||||
);
|
||||
});
|
||||
|
||||
it('rejects runtime path traversal before touching MinIO', async () => {
|
||||
const minio = createMinio();
|
||||
const service = new BlogLive2DAssetService(
|
||||
|
||||
Loading…
Reference in New Issue
Block a user