попробовать {} без catch {} можно в JavaScript?

115

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

Итак, в основном то, что у меня сейчас есть:

function testAll() {
    try { return func1(); } catch(e) {}
    try { return func2(); } catch(e) {} // If func1 throws error, try func2
    try { return func3(); } catch(e) {} // If func2 throws error, try func3
}

Но на самом деле я бы хотел только tryвернуть его (т.е. если он не выдаст ошибку). catchБлок мне не нужен . Однако такой код try {}не работает, потому что в нем отсутствует (неиспользуемый) catch {}блок.

Я поместил пример на jsFiddle .

Итак, есть ли способ catchудалить эти блоки при достижении того же эффекта?

pimvdb
источник

Ответы:

5

Нет. Вы должны их оставить.

Это действительно имеет смысл, поскольку ошибки вообще не следует игнорировать.

ThiefMaster
источник
16
В этом случае эти функции не должны nullreturn func1() || func2() || func3();
выдавать
53
Этот ответ фактически неверен, вы можете получить, try {}; finally {}как показано в stackoverflow.com/a/5764505/68210
Daniel X Moore
4
@DanielXMoore, без catch (e) {}исключения, выброшенное исключение func1()предотвратило бы попытку func2().
binki
67
Иногда имеет смысл иметь пустой улов, поэтому я не согласен с вашим аргументом.
Петр Пеллер
9
Этот ответ фактически неверен и вводит в заблуждение. «Это действительно имеет смысл», - говорите вы, но ошибаетесь, это имеет смысл только в некоторых случаях, но не в других. Это отличный пример необъяснимого принятия ужасного ответа. Есть много случаев, когда имеет смысл не использовать блок catch, как, например, в asyncфункции. Ясно, что язык javascript заставляет создавать пустые catchблоки бессмысленно.
YungGun
237

Попытка без улова пункта отправляет сообщение об ошибке на следующий более высокий улов , или в окно, если нет никакого подвоха определяется в пределах этой попытки.

Если у вас нет ловушки , выражение try требует предложения finally .

try {
    // whatever;
} finally {
    // always runs
}
Kennebec
источник
Так что лучше всего написать что-нибудь вроде try { // whatever; } finally { try { // whatever; } finally { try { // whatever; } finally { try { // whatever; } finally { //always run}}}?
user2284570
1
Вышеприведенный комментарий не дает точного ответа OP, потому что он не хочет запускать функцию 2, если функция 1 завершается успешно.
Эндрю Стейтц
2
Обратите внимание, что попытка без улова не поглотит ошибок .
Дэн Даскалеску 01
Спасибо, это то, что мне было нужно :-) Было бы здорово, если бы он работал и без попытки {} Я имею в виду: async () => {указатьWorkInProgress () await pipelineStep1 () await pipelineStep2 () ... наконец {stopIndicator ( )}} Было бы ясно, что имеется в виду вся функция ;-) Эти блоки try там такие уродливые ...
Ленни
35

Начиная с ES2019 , можно иметь пустой блок catch без переменной ошибки . Это называется необязательной привязкой перехвата и было реализовано в V8 v6.6, выпущенном в июне 2018 года . Эта функция доступна с Node 10 , Chrome 66 , Firefox 58 , Opera 53 и Safari 11.1 .

Синтаксис показан ниже:

try {
  throw new Error("This won't show anything");
} catch { };

Вам все еще нужен catchблок, но он может быть пустым, и вам не нужно передавать никакую переменную. Если вам вообще не нужен блок catch, вы можете использовать try/ finally, но учтите, что он не принимает ошибок, как это делает пустой catch.

try {
  throw new Error("This WILL get logged");
} finally {
  console.log("This syntax does not swallow errors");
}

Дэн Даскалеску
источник
2
этот ответ самый последний! с точки зрения порядка выполнения, 1. он пытается tryблокировать. 2. Ловит ошибку. 3. Выполняет finallyблок. 4. Выдает ошибку. Это верно?
helsont
Спасибо @helsont. Что касается порядка выполнения во втором примере кода, я не уверен, что можно сказать, была ли ошибка обнаружена и повторно выбрана, или просто (возможно) просто выброшена и не обнаружена в первую очередь (поскольку нет catch). Окружите весь код другим try/,catch и вы сможете поймать This WILL get loggedошибку.
Дэн Даскалеску
Теперь выглядит очень чисто. Спасибо, что поделился!
LeOn - Хан Ли
10

Нет, catch(or finally) - tryдруг пользователя и всегда рядом в рамках try / catch .

Однако вполне допустимо, чтобы они были пустыми, как в вашем примере.

В комментариях к вашему примеру кода ( если func1 выдает ошибку, попробуйте func2 ), может показаться, что вы действительно хотите вызвать следующую функцию внутриcatch блока предыдущего.

Алекс
источник
1
Вы правы. Однако, если такой код try {...}; try {...}возможен, смысл кода может быть более ясным (попробуйте первое, в противном случае попробуйте второе).
pimvdb
О вашем редактировании: в примере JSFiddle вторая функция что-то возвращает, поэтому действительно ли третья функция оценивается в этом случае? Я думал, что returnзаявление останавливает все, что идет после него.
pimvdb
@pimvdb Извините, скрипку не проверял. returnвызовет преждевременный возврат функции. Я обновлю свой ответ.
Alex
1
Этот ответ фактически неверен, вы можете получить, try {}; finally {}как показано в stackoverflow.com/a/5764505/68210
Daniel X Moore
1
@DanielXMoore Конечно, но finally{}в основном в том же духе, что и catch{}. Обновлю ответ.
Alex
6

Я бы не рекомендовал try-finally без улова, потому что, если и блок try, и блок finally блокируют ошибки throw, ошибка, выданная в предложении finally, всплывает, а ошибка блока try игнорируется в моем собственном тесте:

try {
  console.log('about to error, guys!');
  throw new Error('eat me!');
} finally {
  console.log ('finally, who cares');
  throw new Error('finally error');
}

Результат:

>     about to error, guys!
>     finally, who cares
>     .../error.js:9
>         throw new Error('finally error');
>         ^
>     
>     Error: finally error
Джо Б.
источник
1

Они работают вместе на всех известных мне языках, где они есть (JavaScript, Java, C #, C ++). Не делай этого.

duffymo
источник
1
Странно, что мой был отвергнут пятью годами позже, когда он говорит то же самое, что и другие ответы здесь. Кажется, моя единственная была отвергнута. Учтите, модераторы.
duffymo
У Tcl очень удобная конструкция из одного словаcatch {my code}
MKaama
Зачем? Чувствует себя бесполезным, если только не попробую / наконец.
duffymo 01
1

Я решил взглянуть на поставленную проблему под другим углом.

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

код можно увидеть на http://jsfiddle.net/Abyssoft/RC7Nw/4/

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

В соответствии с требованиями stackoverflow, здесь есть встроенный код [отредактирован, чтобы сделать JSLint совместимым (удалить ведущие пробелы для подтверждения), улучшить читаемость]

function func1() {"use strict"; throw "I don't return anything"; }
function func2() {"use strict"; return 123; }
function func3() {"use strict"; throw "I don't return anything"; }

// ctr = Code to Run <array>, values = values <array>, 
// eh = error code can be blank.
// ctr and params should match 1 <-> 1
// Data validation not done here simple POC
function testAll(ctr, values, eh) {
    "use strict";
    var cb; // cb = code block counter
    for (cb in ctr) {
        if (ctr.hasOwnProperty(cb)) {
            try {
                return ctr[cb](values[cb]);
            } catch (e) {
                if (typeof eh[cb] === "function") {
                    eh[cb](e);
                } else {
                    //error intentionally/accidentially ignored
                    console.log(e);
                }
            }
        }
    }
    return false;
}

window.alert(testAll([func1, func2, func3], [], []));

Взаимодействие с другими людьми

user1800957
источник
1

Если вы хотите, чтобы при возникновении ошибки срабатывали только функции 2 и 3, почему вы не помещаете их в блок catch?

function testAll() {
  try {
    return func1();
  } catch(e) {
    try {
      return func2();
    } catch(e) {
      try {
        return func3();
      } catch(e) {
        // LOG EVERYTHING FAILED
      }
    }
  }
}
танк
источник
0

Я считаю, что вам нужно использовать вспомогательную функцию, например:

function tryIt(fn, ...args) {
    try {
        return fn(...args);
    } catch {}
}

и используйте его как:

tryIt(function1, /* args if any */);
tryIt(function2, /* args if any */);
Итай Мерчав
источник
-2

Начиная с ES2019 вы можете легко использовать try {}без catch {}:

try {
  parseResult = JSON.parse(potentiallyMalformedJSON);
} catch (unused) {}

Для получения дополнительной информации, пожалуйста, обратитесь к предложению Майкла Фиккара.

Джеймс Дж. Гудвин
источник
1
Нет, catchпо-прежнему требуется, просто привязка не требуется ...
chipit24 06