160 lines
6.1 KiB
TypeScript
160 lines
6.1 KiB
TypeScript
/**
|
|
* 下载错误代码和消息定义
|
|
* 统一管理所有下载相关的错误提示
|
|
*/
|
|
|
|
export enum DownloadErrorCode {
|
|
// 权限相关
|
|
UNAUTHORIZED = 'UNAUTHORIZED',
|
|
FORBIDDEN = 'FORBIDDEN',
|
|
NO_PERMISSION = 'NO_PERMISSION',
|
|
VIDEO_WAIT_PERIOD = 'VIDEO_WAIT_PERIOD',
|
|
|
|
// 文件不存在
|
|
MATERIAL_NOT_FOUND = 'MATERIAL_NOT_FOUND',
|
|
FILE_NOT_FOUND = 'FILE_NOT_FOUND',
|
|
FILE_MISSING = 'FILE_MISSING', // 新增:源文件缺失(明确标识)
|
|
PSD_NOT_FOUND = 'PSD_NOT_FOUND',
|
|
NO_DOWNLOADABLE_FILES = 'NO_DOWNLOADABLE_FILES',
|
|
|
|
// 网络/存储
|
|
S3_ACCESS_FAILED = 'S3_ACCESS_FAILED',
|
|
NETWORK_ERROR = 'NETWORK_ERROR',
|
|
FILE_READ_ERROR = 'FILE_READ_ERROR',
|
|
|
|
// 数据错误
|
|
INVALID_DOWNLOAD_TYPE = 'INVALID_DOWNLOAD_TYPE',
|
|
ASSET_TYPE_MISMATCH = 'ASSET_TYPE_MISMATCH',
|
|
BIGINT_SERIALIZATION_ERROR = 'BIGINT_SERIALIZATION_ERROR',
|
|
|
|
// 处理错误
|
|
ZIP_CREATION_FAILED = 'ZIP_CREATION_FAILED',
|
|
STREAM_ERROR = 'STREAM_ERROR',
|
|
UNKNOWN_ERROR = 'UNKNOWN_ERROR',
|
|
}
|
|
|
|
/**
|
|
* 错误消息映射(中文)
|
|
*/
|
|
export const DownloadErrorMessages: Record<DownloadErrorCode, string> = {
|
|
[DownloadErrorCode.UNAUTHORIZED]: '请先登录',
|
|
[DownloadErrorCode.FORBIDDEN]: '您的下载权限已被限制,请联系管理员',
|
|
[DownloadErrorCode.NO_PERMISSION]: '无权限下载该素材',
|
|
[DownloadErrorCode.VIDEO_WAIT_PERIOD]: '视频类素材上传后满 15 天才能下载',
|
|
|
|
[DownloadErrorCode.MATERIAL_NOT_FOUND]: '素材不存在',
|
|
[DownloadErrorCode.FILE_NOT_FOUND]: '源文件已丢失(可能被清空),可尝试下载预览图',
|
|
[DownloadErrorCode.FILE_MISSING]: '没有源文件,可联系作者重新上传',
|
|
[DownloadErrorCode.PSD_NOT_FOUND]: 'PSD 文件不存在',
|
|
[DownloadErrorCode.NO_DOWNLOADABLE_FILES]: '没有可下载的文件',
|
|
|
|
[DownloadErrorCode.S3_ACCESS_FAILED]: '存储服务访问失败,请稍后重试',
|
|
[DownloadErrorCode.NETWORK_ERROR]: '网络连接失败,请检查网络后重试',
|
|
[DownloadErrorCode.FILE_READ_ERROR]: '文件读取失败,请稍后重试',
|
|
|
|
[DownloadErrorCode.INVALID_DOWNLOAD_TYPE]: '无效的下载类型',
|
|
[DownloadErrorCode.ASSET_TYPE_MISMATCH]: '文件类型不匹配,请联系管理员',
|
|
[DownloadErrorCode.BIGINT_SERIALIZATION_ERROR]: '数据处理错误,请稍后重试',
|
|
|
|
[DownloadErrorCode.ZIP_CREATION_FAILED]: '文件打包失败,请稍后重试',
|
|
[DownloadErrorCode.STREAM_ERROR]: '文件流读取失败,请稍后重试',
|
|
[DownloadErrorCode.UNKNOWN_ERROR]: '下载失败,请稍后重试',
|
|
};
|
|
|
|
/**
|
|
* 下载错误响应接口
|
|
*/
|
|
export interface DownloadErrorResponse {
|
|
error: string;
|
|
code?: DownloadErrorCode;
|
|
details?: string;
|
|
}
|
|
|
|
/**
|
|
* 创建标准化的错误响应
|
|
*/
|
|
export function createDownloadError(
|
|
code: DownloadErrorCode,
|
|
details?: string
|
|
): DownloadErrorResponse {
|
|
return {
|
|
error: DownloadErrorMessages[code],
|
|
code,
|
|
...(details && { details }),
|
|
};
|
|
}
|
|
|
|
/**
|
|
* 根据错误代码获取用户友好的错误消息
|
|
*/
|
|
export function getDownloadErrorMessage(code?: DownloadErrorCode | string): string {
|
|
if (!code) {
|
|
return DownloadErrorMessages[DownloadErrorCode.UNKNOWN_ERROR];
|
|
}
|
|
|
|
// 如果是字符串,尝试转换为枚举
|
|
const errorCode = Object.values(DownloadErrorCode).includes(code as DownloadErrorCode)
|
|
? (code as DownloadErrorCode)
|
|
: DownloadErrorCode.UNKNOWN_ERROR;
|
|
|
|
return DownloadErrorMessages[errorCode as DownloadErrorCode] || DownloadErrorMessages[DownloadErrorCode.UNKNOWN_ERROR];
|
|
}
|
|
|
|
/**
|
|
* 从错误对象中提取错误代码和消息
|
|
*/
|
|
export function parseDownloadError(error: any): {
|
|
code: DownloadErrorCode;
|
|
message: string;
|
|
details?: string;
|
|
} {
|
|
// 如果已经是标准化的错误响应
|
|
if (error?.code && Object.values(DownloadErrorCode).includes(error.code as DownloadErrorCode)) {
|
|
const code = error.code as DownloadErrorCode;
|
|
return {
|
|
code,
|
|
message:
|
|
code === DownloadErrorCode.VIDEO_WAIT_PERIOD
|
|
? error.details || error.error || DownloadErrorMessages[code]
|
|
: error.error || DownloadErrorMessages[code],
|
|
details: error.details,
|
|
};
|
|
}
|
|
|
|
// 如果是字符串错误消息,尝试匹配错误代码
|
|
const errorMessage = error?.error || error?.message || String(error);
|
|
|
|
// 根据错误消息内容推断错误类型
|
|
// 优先检查更具体的错误类型
|
|
if (errorMessage.includes('没有源文件') || errorMessage.includes('源文件缺失') || errorMessage.includes('联系作者')) {
|
|
return { code: DownloadErrorCode.FILE_MISSING, message: DownloadErrorMessages[DownloadErrorCode.FILE_MISSING] };
|
|
}
|
|
if (errorMessage.includes('未登录') || errorMessage.includes('请先登录')) {
|
|
return { code: DownloadErrorCode.UNAUTHORIZED, message: DownloadErrorMessages[DownloadErrorCode.UNAUTHORIZED] };
|
|
}
|
|
if (errorMessage.includes('权限') || errorMessage.includes('无权限')) {
|
|
return { code: DownloadErrorCode.NO_PERMISSION, message: DownloadErrorMessages[DownloadErrorCode.NO_PERMISSION] };
|
|
}
|
|
if (errorMessage.includes('满 15 天') || errorMessage.includes('上传后')) {
|
|
return { code: DownloadErrorCode.VIDEO_WAIT_PERIOD, message: DownloadErrorMessages[DownloadErrorCode.VIDEO_WAIT_PERIOD], details: error?.details };
|
|
}
|
|
if (errorMessage.includes('不存在') || errorMessage.includes('not found')) {
|
|
return { code: DownloadErrorCode.FILE_NOT_FOUND, message: DownloadErrorMessages[DownloadErrorCode.FILE_NOT_FOUND] };
|
|
}
|
|
if (errorMessage.includes('S3') || errorMessage.includes('存储')) {
|
|
return { code: DownloadErrorCode.S3_ACCESS_FAILED, message: DownloadErrorMessages[DownloadErrorCode.S3_ACCESS_FAILED] };
|
|
}
|
|
if (errorMessage.includes('网络') || errorMessage.includes('network')) {
|
|
return { code: DownloadErrorCode.NETWORK_ERROR, message: DownloadErrorMessages[DownloadErrorCode.NETWORK_ERROR] };
|
|
}
|
|
if (errorMessage.includes('BigInt')) {
|
|
return { code: DownloadErrorCode.BIGINT_SERIALIZATION_ERROR, message: DownloadErrorMessages[DownloadErrorCode.BIGINT_SERIALIZATION_ERROR] };
|
|
}
|
|
|
|
// 默认未知错误
|
|
return {
|
|
code: DownloadErrorCode.UNKNOWN_ERROR,
|
|
message: errorMessage || DownloadErrorMessages[DownloadErrorCode.UNKNOWN_ERROR],
|
|
};
|
|
}
|