补充数据库备份上传错误日志
为 OSS 上传失败补充备份对象路径上下文 输出错误 cause 链和网络字段,便于定位 fetch failed (cherry picked from commit 48ee0eb75dd84e2db95f828b256f233e6618f5d9)
This commit is contained in:
@@ -396,16 +396,21 @@ async function uploadArchive({archivePath, bucket, endpoint, objectKey, accessKe
|
||||
});
|
||||
|
||||
console.log(`[database-backup] 上传 OSS: oss://${bucket}/${objectKey}`);
|
||||
const response = await fetch(targetUrl, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
...headers,
|
||||
authorization,
|
||||
'content-length': String(fileStat.size),
|
||||
},
|
||||
body: createReadStream(archivePath),
|
||||
duplex: 'half',
|
||||
});
|
||||
let response;
|
||||
try {
|
||||
response = await fetch(targetUrl, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
...headers,
|
||||
authorization,
|
||||
'content-length': String(fileStat.size),
|
||||
},
|
||||
body: createReadStream(archivePath),
|
||||
duplex: 'half',
|
||||
});
|
||||
} catch (error) {
|
||||
throw new Error(`OSS 上传请求失败: oss://${bucket}/${objectKey}`, {cause: error});
|
||||
}
|
||||
|
||||
const responseText = await response.text();
|
||||
if (!response.ok) {
|
||||
@@ -584,7 +589,49 @@ async function main() {
|
||||
}
|
||||
}
|
||||
|
||||
function formatErrorDetails(error) {
|
||||
if (!error || typeof error !== 'object') {
|
||||
return '';
|
||||
}
|
||||
return ['code', 'errno', 'syscall', 'hostname', 'host', 'port', 'address']
|
||||
.map((field) => {
|
||||
const value = error[field];
|
||||
return value === undefined || value === null || value === '' ? '' : `${field}=${String(value)}`;
|
||||
})
|
||||
.filter(Boolean)
|
||||
.join(' ');
|
||||
}
|
||||
|
||||
function describeError(error) {
|
||||
const lines = [];
|
||||
let current = error;
|
||||
for (let depth = 0; current && depth < 5; depth += 1) {
|
||||
const label = depth === 0 ? 'error' : `cause[${depth}]`;
|
||||
if (!(current instanceof Error)) {
|
||||
lines.push(`${label}: ${String(current)}`);
|
||||
break;
|
||||
}
|
||||
|
||||
lines.push(`${label}: ${current.name}: ${current.message}`);
|
||||
const details = formatErrorDetails(current);
|
||||
if (details) {
|
||||
lines.push(`${label} details: ${details}`);
|
||||
}
|
||||
if (current instanceof AggregateError) {
|
||||
current.errors.slice(0, 3).forEach((item, index) => {
|
||||
const itemText = item instanceof Error ? `${item.name}: ${item.message}` : String(item);
|
||||
const itemDetails = formatErrorDetails(item);
|
||||
lines.push(`${label}.errors[${index}]: ${itemText}${itemDetails ? ` (${itemDetails})` : ''}`);
|
||||
});
|
||||
}
|
||||
current = current.cause;
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
console.error(`[database-backup] ${error instanceof Error ? error.message : String(error)}`);
|
||||
for (const line of describeError(error)) {
|
||||
console.error(`[database-backup] ${line}`);
|
||||
}
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user