#node.js #promise
#node.js #обещание
Вопрос:
Я подозреваю, что есть какая-то проблема с кодом, и это, скорее всего, в части catch, которая в целом приводит к сбою серверного приложения.
Цель: В основном проверка типа ошибки, которая может быть обработана, например, если объект не существует, для всех других ошибок корректно отклоните их обратно вызывающему без сбоя приложения.
const Article = require("Article");
function upload(row) {
return new Promise(function(resolve, reject){
Article.requestData(row.schema) // if exists
.then(Article.upload.bind(null, row.article)) //may throw error
.then(resolve) // done if OK
.catch(function(error){
if(error.code == "NotFoundException") { // entity doesn't exists
Article.create(row.schema) // create entity
.then(Article.upload.bind(null, row.article)) // upload
.then(resolve, reject); // reject upload error
} else { // upload errors
// reject(error); // tried reject
throw error; // trying re-throw
}
});
});
}
Код сначала пытается получить информацию о сущности, и если она не найдена, он создает ее.
Теперь часть загрузки может выдавать ошибку, которую мне нужно корректно отправить обратно вызывающему.
Ошибка, которую я получаю, это UnhandledPromiseRejectionWarning
Ответ №1:
Тот же код, но переписанный.
function upload(row) {
return Article.requestData(row.schema) // if exists
.then(Article.upload.bind(null, row.article)) //may throw error
.catch(function(error){
if(error.code == "NotFoundException") { // entity doesn't exists
return Article.create(row.schema) // create entity
.then(Article.upload.bind(null, row.article)) // upload
} else {
throw error;
});
}
Запуск new Promise()
часто называют антишаблоном. Иногда вы не можете легко обойти это, но это типичный случай, когда это совершенно не нужно.
Каждый раз, когда вы вызываете .then()
or .catch()
, возвращается новое обещание, и это то же самое обещание, которое вы хотите вернуть из своей функции.
Вот версия async / await, просто для удовольствия:
async function upload(row) {
try {
await Article.requestData(row.schema) // if exists
await Article.upload.bind(row.article);
} catch (error) {
if(error.code == "NotFoundException") { // entity doesn't exists
await Article.create(row.schema) // create entity
await Article.upload(row.article);
} else {
throw error;
}
}
}
Комментарии:
1. спасибо за переписывание, но это не то, что я ищу, причина и решение, почему предложение else терпит неудачу, несмотря на антишаблон, не могли бы вы, пожалуйста, осветить реальную проблему.
2. есть ли проблема с вызовом reject в разделе catch?
3. @Разработчик одна из основных ошибок заключается в том, что вы не возвращаетесь из нескольких ваших цепочек обещаний, что означает, что если в них возникают ошибки, они «проглатываются» и никогда не обрабатываются. Все ваши цепочки обещаний должны возвращать свой результат обратно (как обещание) в основную функцию. Мой ответ — самое разумное решение для этого, но если вы хотите сохранить свою версию для спагетти, убедитесь, что вы также улавливаете ошибки из вашей второй цепочки обещаний.
4. Обратите внимание, что в моей версии каждый раз, когда я запускаю цепочку обещаний, я возвращаю ее. (Article.requesData и article.upload). Но перенастройка в вашем случае ничего не даст из-за использования new Promise, поэтому ваш единственный вариант — добавить
catch
предложения к каждому и молиться, чтобы в ваших заключительных предложениях catch не возникло ошибки5.
one major mistake is that you are not returning from several of your promise-chains
это ценно. Теперь я понимаю антипаттерн, и, к счастью, у меня есть правильный подход с вашей стороны, но просто чтобы понять и устранить проблему, что бы вы сделали, чтобы исправить мою версию так, как она есть, с обещанием оболочки. Это поможет мне лучше понять. Пожалуйста, предоставьте кодовое решение в другой правке под вашим данным ответом. Еще раз спасибо.