NodeJS中Promise被拒绝后后续.then仍执行的问题求助
问题根源
你的checkIfProjectExistsOnNexus函数末尾额外加了一个.catch(),这个回调只打印错误日志但没有重新抛出错误或返回rejected状态的Promise,导致本该传递下去的reject被“吞掉”——Promise链会认为这个函数执行成功,因此继续走后续的.then()流程。
修复步骤
1. 修正checkIfProjectExistsOnNexus的错误处理
去掉函数末尾的.catch(),让reject状态正常传递到主Promise链中:
function checkIfProjectExistsOnNexus(projectPomDescription, projectDescription) { return new Promise((resolve, reject) => { const version = argv.type === 'snapshot' ? projectDescription.version.replace('SNAPSHOT','*') : projectDescription.version; nexus.exists( getProjectGroupId(projectPomDescription), projectPomDescription.project.artifactId, version ) .then((value) => { console.log("value "+ value); if (value) { console.log(`Project: ${projectDescription.name} has already been released in version ${projectDescription.version}, project skipped.`); // 传递具体错误信息,方便后续catch处理 reject(new Error('Project already exists on Nexus')); return; } resolve(); }) .catch(reject); // 直接把nexus的错误传递出去 }); // 移除这里的.catch,不要吞掉reject状态 }
2. 修正主Promise链的结构
原来的主链中,push操作的.then()内部嵌套了后续逻辑,且catch只在嵌套链内部,会导致前面的错误无法被捕获。改成扁平链式结构,并把catch放在最外层,确保所有错误都能触发errorCallback:
execGitCommand(projectDir, `clone -b ${sourceBranch} ${projectDescription.url} ${projectDir}`, false) .then(() => loadProjectPoms(projectDir, projectPoms)) .then((value) => { projectPomDescription = value; return checkIfProjectExistsOnNexus(projectPomDescription, projectDescription); }) .then(() => execGitCommand(projectDir, `rebase origin/${destinationBranch}`)) .then(() => updateProjectVersion(projectDescription, projectDir)) .then(() => updateProjectPoms(projectDescription, projectDir)) .then(() => execGitCommand(projectDir,"add -u")) .then(() => execGitCommand(projectDir,`commit -m "Set version ${projectDescription.version}"`)) .then(() => execGitCommand(projectDir,`push origin ${sourceBranch}`)) .then(waitingCallback) .then(() => waitNexusRelease(projectDescription, projectPoms, projectPomDescription, project)) .then(completeCallback) .catch(errorCallback); // 最外层catch捕获所有链上的错误
可选优化:用async/await重构(可读性更高)
Promise链式调用嵌套多了容易混乱,换成async/await语法后,错误处理更直观,逻辑流程一目了然:
async function runReleaseWorkflow() { try { // 克隆代码 await execGitCommand(projectDir, `clone -b ${sourceBranch} ${projectDescription.url} ${projectDir}`, false); // 加载POM文件 const projectPomDescription = await loadProjectPoms(projectDir, projectPoms); // 检查Nexus是否存在该版本,不存在才继续 await checkIfProjectExistsOnNexus(projectPomDescription, projectDescription); // 后续仅在check通过时执行 await execGitCommand(projectDir, `rebase origin/${destinationBranch}`); await updateProjectVersion(projectDescription, projectDir); await updateProjectPoms(projectDescription, projectDir); await execGitCommand(projectDir,"add -u"); await execGitCommand(projectDir,`commit -m "Set version ${projectDescription.version}"`); await execGitCommand(projectDir,`push origin ${sourceBranch}`); await waitingCallback(); await waitNexusRelease(projectDescription, projectPoms, projectPomDescription, project); completeCallback(); } catch (error) { errorCallback(error); } } // 执行工作流 runReleaseWorkflow();
内容的提问来源于stack exchange,提问作者Kamila Nowak
相关产品推荐
相关产品推荐

