Как остановить функцию при получении объекта Error?

Как остановить функцию в момент возникновения ошибки.

Я делаю HTTP-вызов. Я построил функцию обратного вызова в стиле ошибки.

Как остановить функцию обратного вызова, если в нее был передан объект Error? В моем случае мне нужно остановиться независимо от типа ошибки, так как мне нужен объект данных для последующей цепочки функций обратного вызова.

Это просто return? Я прочитал, что делает return на более высоком уровне, поэтому надеюсь получить подтверждение, подходит ли мой код для того, чего я хотел бы достичь.

Я просто хочу убедиться, что текущие функции обратного вызова не продолжаются, поскольку им не будут передаваться какие-либо объекты данных, поэтому все они будут «ошибками».

сервер.js

var request = function(callback) {
  // HTTP call to server
      },  
      function (error, response, body) {    
      if (!error && response.statusCode === 200) {
        // processed and created data object
          return callback(null, data)
      }
      else {
         console.log(error.stack)
         return callback(error) ;
      }
    })
};
var requestSync = Meteor.wrapAsync(request);


var callback = function(error, data, callback) {
  if (error) {
    // How do I properly stop this function?
     return callback(new Error('custom message I send to client'))
  }
  else {
    // doing something with data object..
  }
}

Функции вызываются внутри моего метода.

try {
  var resultOne = requestSync()
  var resultTwo = callback(resultOne)
  // more async callback functions will reside here
} catch (e) {
  console.error('error occured somehwere = ' + e);
} finally {
//
}

person meteorBuzz    schedule 24.02.2015    source источник
comment
Я думаю, что вы ищете ключевое слово return в обратном вызове. если (ошибка) вернуть обратный вызов (новая ошибка (...)) Или, возможно, бросить ключевое слово, если (ошибка) бросить новую ошибку (...)   -  person SnowInferno    schedule 24.02.2015
comment
Я пропустил возврат по ошибке, но мне любопытно узнать, правильный ли это способ добиться того, чего я хочу. Затем я смогу адаптировать обработку ошибок в зависимости от контекста в других случаях.   -  person meteorBuzz    schedule 24.02.2015


Ответы (2)


Я раньше не видел точно такого способа кодирования, поэтому трудно комментировать, правильный ли это способ, не зная немного больше о том, что вы действительно пытаетесь сделать. Я предполагаю, что блок:

try {
  var resultOne = requestSync()
  var resultTwo = callback(resultOne)
  // more async callback functions will reside here
} catch (e) {
  console.error('error occured somehwere = ' + e);
} finally {
}

... вызывает другую функцию «обратного вызова», чем в первом фрагменте кода (иначе вы передаете resultOne в качестве первого параметра, и функция обратного вызова будет считать это допустимым объектом ошибки и выдаст ошибку).

Однако, чтобы ответить на ваш вопрос, будет ли код продолжать работать, если одна из функций выдаст ошибку, ответ будет отрицательным — он перейдет непосредственно к блоку catch. Взгляните на: эту документацию по адресу MDN

Особенно эта часть:

Предложение catch содержит операторы, которые определяют, что делать, если в блоке try возникнет исключение. То есть вы хотите, чтобы блок try завершился успешно, а в случае неудачи вы хотите, чтобы управление передавалось блоку catch. Если какой-либо оператор в блоке try (или в функции, вызываемой из блока try) выдает исключение, управление немедленно переходит к предложению catch. Если в блоке try не выдается исключение, предложение catch пропускается.

Я надеюсь, что это отвечает на ваш основной вопрос. Поскольку вы, кажется, заключаете все асинхронные вызовы в Meteor.wrapAsync(), им следует дождаться возврата результата, прежде чем вызывать следующую функцию, если она реализована правильно. Я могу порекомендовать просмотреть этот ответ для получения дополнительной информации о правильном способе реализации wrapAsync и обработки ошибок.

ОБНОВЛЕНИЕ

Я подумал, что было бы интересно сделать пример, так как этот пост уже становится длинным. Взгляните на этот пример, который я загрузил на Github, он может дать вам нужные ответы.

Так всегда ли объект «ошибка», возвращаемый из http-вызова, распознается как объект ошибки?

Итак, fibers/future предполагает стандартный обратный вызов узла в качестве последнего аргумента с объектом ошибки в качестве первого параметра и объектом результата в качестве второго. Пока это так, ошибка будет перехвачена в блоке «поймать», и выполнение будет остановлено.

Если да, то как я могу добавить еще одно поле, чтобы ошибка имела смысл для меня?

Не уверен, что именно вы здесь думаете, но взгляните на мой пример на Github. Там я создаю объект ошибки. Если вы вместо использования setTimeout (где я просто моделирую асинхронный вызов), создайте свою функцию таким же образом, поймайте объект ошибки из удаленного вызова, добавьте к нему поле или измените err.message на что-то более значимое для вас, а затем вызовите обратный вызов. Думаю, это должно сработать, но я не проверял именно это.

Если есть ошибка, но объект ошибки не передается, каково соглашение узла для создания объекта ошибки, который я могу вернуть?

См. пример еще раз. wrapAsync работает только на сервере, предполагается, что функция, которую вы вызываете, имеет обратный вызов в качестве последнего (или единственного) параметра. Этот обратный вызов должен иметь ошибку в качестве первого параметра и результат в качестве второго. Большинство функций узла (если не все) будут соответствовать этим правилам.

Если вы по какой-то причине хотите обработать обратный вызов самостоятельно, вам нужно обязательно вызвать обратный вызов вручную и передать «null» в качестве первого параметра, если нет ошибки, или создать объект ошибки и передать его как первый параметр, если есть ошибка. Посмотрите в примере на wrapAsyncTest.js.

person cfs    schedule 24.02.2015
comment
Да, это важно, однако Meteor.wrapAsync() использует Fibers, чтобы асинхронный код выглядел как синхронный, поэтому при правильном использовании операторы должны вызываться один за другим. Это своего рода альтернатива обещаниям для предотвращения множества вложенных обратных вызовов. - person cfs; 25.02.2015
comment
Так всегда ли объект «ошибка», возвращаемый из http-вызова, распознается как объект ошибки? Если да, то как я могу добавить еще одно поле, чтобы ошибка имела смысл для меня? ЕСЛИ есть ошибка, но объект ошибки не передается, каково соглашение узла для создания объекта ошибки, который я могу вернуть? Спасибо @cfs за информацию. - person meteorBuzz; 26.02.2015
comment
Поскольку я обернул свою функцию в асинхронный Meteor.wrap, а иногда и с использованием будущей библиотеки, функция по-прежнему асинхронная, но поведение функции «как синхронное». Это означает, что я могу инициировать обернутый асинхронный код один за другим, где каждый ждет возврата результатов и НЕ блокирует цикл событий. - person meteorBuzz; 26.02.2015
comment
@cfs, опубликованный вами пример gutHub очень полезен для объяснения фундаментального процесса. Это служит моей цели, чтобы обрабатывать мои ошибки. Спасибо - person meteorBuzz; 09.03.2015

больше шаблона node.js, но вот что я использую:

if (err) return callback(err, null);
console.log("no error here!");
callback(err, result);
person Matt K    schedule 24.02.2015