Почему Исключения, как говорят, так плохи для Контроля ввода?

Похоже, body-parser поддерживал загрузку файлов в Express 3, но поддержка была сброшена для Express 4, когда больше не включалась в Connect как зависимость

]

После просмотра некоторых модулей в ответе mscdex я обнаружил, что express-busboy был намного лучшей альтернативой и ближайшей заменой. Единственные различия, которые я заметил, были в свойствах загруженного файла.

console.log(req.files) с использованием body-parser (Express 3) выводит объект, который выглядит следующим образом:

{ file: 
   { fieldName: 'file',
     originalFilename: '360px-Cute_Monkey_cropped.jpg',
     name: '360px-Cute_Monkey_cropped.jpg'
     path: 'uploads/6323-16v7rc.jpg',
     type: 'image/jpeg',
     headers: 
      { 'content-disposition': 'form-data; name="file"; filename="360px-Cute_Monkey_cropped.jpg"',
        'content-type': 'image/jpeg' },
     ws: 
      WriteStream { /* ... */ },
     size: 48614 } }

по сравнению с console.log(req.files) с использованием экспресс-шины (Экспресс 4):

{ file: 
   { field: 'file',
     filename: '360px-Cute_Monkey_cropped.jpg',
     file: 'uploads/9749a8b6-f9cc-40a9-86f1-337a46e16e44/file/360px-Cute_Monkey_cropped.jpg',
     mimetype: 'image/jpeg',
     encoding: '7bit',
     truncated: false
     uuid: '9749a8b6-f9cc-40a9-86f1-337a46e16e44' } }

48
задан Community 23 May 2017 в 12:10
поделиться

13 ответов

Читая эти ответы, я нахожу его очень бесполезным для высказывания, "Исключения должны только использоваться для исключительных условий". Это вызывает целый вопрос того, что является "исключительным условием". Это - субъективный термин, лучшим определением которого является "любое условие, с которым не имеет дело Ваш нормальный логический поток". Другими словами, исключительное условие является любым условием, Вы имеете дело с использованием исключений.

все хорошо с этим как определение, я не знаю, что мы доберемся немного ближе, чем это так или иначе. Но необходимо знать, что это - определение, которое Вы используете.

, Если Вы собираетесь привести доводы против исключений в определенном случае, необходимо объяснить, как разделить вселенную условий в "исключительный" и "неисключительное".

До некоторой степени, это подобно ответу на вопрос, "где границы между процедурами?" Ответ, "Везде, где Вы помещаете начинание и конец", и затем мы можем говорить об эмпирических правилах и различных стилях для определения, куда поместить их. Нет никаких жестких правил.

31
ответ дан Ned Batchelder 26 November 2019 в 18:47
поделиться

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

0
ответ дан asplake 26 November 2019 в 18:47
поделиться

Я соглашаюсь с Mitch, что это "Исключения не должно использоваться для нормального потока управления". Я просто хочу добавить, что от того, что я помню от своих занятий по информатике, ловля исключений является дорогой. Я действительно никогда не пытался сделать сравнительные тесты, но было бы интересно выдержать сравнение, производительность между говорят, если/еще по сравнению с попыткой/выгодой.

0
ответ дан barneytron 26 November 2019 в 18:47
поделиться

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

public bool isValidDate(string date)
{
    bool retVal = true;
    //check for 4 digit year
    throw new FourDigitYearRequiredException();
    retVal = false;

    //check for leap years
    throw new NoFeb29InANonLeapYearException();
    retVal = false;
    return retVal;
}

Этот код имеет тенденцию быть довольно хрупким и твердым поддержать, поскольку правила накапливаются за месяцы и годы. Я обычно предпочитаю разбивать свои проверки в меньшие методы тот возврат bools. Это помогает настроить правила.

public bool isValidDate(string date)
{
    bool retVal = false;
    retVal = doesDateContainAFourDigitYear(date);
    retVal = isDateInALeapYear(date);
    return retVal;
}

public bool isDateInALeapYear(string date){}

public bool doesDateContainAFourDigitYear(string date){}

, Как уже был упомянут, возвратив ошибочную структуру/объект, содержащую информацию об ошибке, прекрасная идея. Так как самое очевидное преимущество - это, можно собрать их и отобразить все сообщения об ошибках пользователю сразу вместо того, чтобы заставить их играть Сильный удар Родинки с проверкой.

1
ответ дан ScottKoon 26 November 2019 в 18:47
поделиться

Исключения не должны использоваться для контроля ввода, потому что не только должен исключения использоваться при исключительных обстоятельствах (который, как на него указали, неправильная пользовательская запись не), но они создают исключительный код (не в блестящем смысле).

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

Исключения действительно злоупотребились в приложении, я работаю над ежедневной газетой и даже для случая, где пользователь ввел неправильный пароль при входе в систему, который логикой будет результатом исключения, потому что это не то, что хочет приложение. Однако, когда процесс имеет один из двух результатов, или корректных или неправильных, я не думаю, что мы можем сказать, что, неправильный, неважно, как неправильно, является исключительным.

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

Сохраняют исключения для действительно исключительного выполнения не просто неправильно. В случае я выделялся, понимание превратно Вашего пароля не является исключительным, но не бывший способный связываться с доменным сервером может быть!

1
ответ дан Toby Allen 26 November 2019 в 18:47
поделиться

Другое голосование против обработки исключений для вещей, которые не являются исключениями!

  1. В.NET JIT-компилятор не выполнит оптимизацию в определенных случаях, даже когда исключения не выдаются. Следующие статьи объясняют его хорошо. http://msmvps.com/blogs/peterritchie/archive/2007/06/22/performance-implications-of-try-catch-finally.aspx http://msmvps.com/blogs/peterritchie/archive/2007/07/12/performance-implications-of-try-catch-finally-part-two.aspx

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

2
ответ дан Alex 26 November 2019 в 18:47
поделиться

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

существуют проблемы производительности за исключениями, но в коде GUI Вы не должны будете обычно волноваться о них. Таким образом, что, если проверка берет дополнительные 100 мс для выполнения? Пользователь не собирается замечать это.

До некоторой степени это - непростое решение - С одной стороны, Вы не могли бы хотеть обрушиваться свое целое приложение, потому что пользователь ввел дополнительную цифру в текстовое поле почтового индекса, и Вы забыли обрабатывать исключение. На другом, 'сбой рано, сбой трудно' подход гарантирует, что ошибки обнаружены и зафиксировали быстро и сохраняют Вашу драгоценную базу данных нормальной. В целом я думаю, что большинство платформ рекомендует не использовать обработку исключений для проверки ошибок UI, и некоторые, как.NET Windows Forms, обеспечивают хорошие способы сделать это (события ErrorProviders и Validation) без исключений.

1
ответ дан Dana Robinson 26 November 2019 в 18:47
поделиться

При использовании исключений код обработки ошибок разделяется от кода, вызывающего ошибку . Это - намерение обработки исключений - быть исключительным условием, ошибка не может быть обработана локально, таким образом, исключение выдается некоторым выше (и неизвестное) объем. Если не обработанный, приложение выйдет, прежде больше трудно сделан.

, Если Вы когда-нибудь, когда-нибудь, когда-либо выдаете исключение при выполнении простых логических операций, как проверка ввода данных пользователем, Вы делаете что-то очень, очень очень, неправильно.

вход не то, что ожидалось и следовательно исключительное.

Этот оператор не устраивает меня вообще. Любой UI ограничивает ввод данных пользователем (например, использование ползунка, который ограничивает минимальные значения / макс. значения) и можно теперь утверждать определенные условия - никакая требуемая обработка ошибок. Или, пользователь может ввести мусор, и Вы ожидаете, что это произойдет, и должны обработать его. Один или другой - нет ничего исключения, идущего здесь безотносительно.

Выдача исключения позволяет мне определять точно, что неправильно было похоже на StringValueTooLong или или IntegerValueTooLow или InvalidDateValue или что бы то ни было. Почему это считают неправильным?

я рассматриваю это вне - ближе к злу. Можно определить абстрактный интерфейс ErrorProvider или возвратить сложный объект, представляющий ошибку, а не простой код. Существуют многие, много опций о том, как Вы получаете сообщения об ошибке. Используя исключения, потому что удобный так, так неправильно . Я чувствую себя грязным просто запись этого абзаца.

Думают о выдаче исключения как надежда. Последний шанс. Молитва. Проверка ввода данных пользователем не должна приводить ни к одному из этих условий.

3
ответ дан Daniel Paull 26 November 2019 в 18:47
поделиться

Действительно ли возможно, что часть разногласия происходит из-за отсутствия согласия о том, что означает 'ввод данных пользователем'? И действительно, в том, какой слой Вы кодируете.

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

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

при кодировании сервера на протокольном уровне Вы могли бы обоснованно ожидать, что клиент проверит ввод данных пользователем. Снова, недопустимый вход здесь действительно был бы исключением. Это очень отличается от доверия клиенту 100% (который был бы очень глуп действительно) - но в отличие от прямого ввода данных пользователем, Вы предсказываете, что большую часть времени исходные данные были бы в порядке. Строки размываются здесь несколько. Чем более вероятно случается так, что что-то происходит, тем меньше Вы хотите использовать исключения для обработки его.

3
ответ дан slim 26 November 2019 в 18:47
поделиться
  1. Пригодность для обслуживания - Исключения создают нечетные пути выполнения кода, мало чем отличаясь от GOTOs.
  2. Простота использования (для других классов) - Другие классы могут положить, что исключениями, повышенными от Вашего класса ввода данных пользователем, являются фактические ошибки
  3. Производительность - На большинстве языков, исключение подвергается штрафу производительности и использования памяти.
  4. Семантика - значение слов действительно имеет значение. Плохой вход не является "исключительным".
5
ответ дан JosephStyons 26 November 2019 в 18:47
поделиться

Я думаю, что различие зависит от контракта конкретного класса, т.е.

Для кода, который предназначен для контакта с вводом данных пользователем и программой оборонительно для него (т.е. санировать его) было бы неправильно выдать исключение для недопустимого входа - это ожидается.

Для кода, который предназначен уже для контакта с санированным и проверил вход, который, возможно, произошел с пользователем, выдав исключение, было бы допустимо, если бы Вы нашли некоторый вход, который предназначен, чтобы быть запрещенным. Код вызова нарушает контракт в этом случае, и это указывает на ошибку в очистке и/или коде вызова.

5
ответ дан frankodwyer 26 November 2019 в 18:47
поделиться

Уже существует один важен другая причина, чем те упомянутые:

при использовании исключений [только 117] для исключительных случаев можно работать в отладчике с отладчиком, устанавливающим "остановку, когда исключение выдается". Это чрезвычайно удобно, потому что Вы заскакиваете в отладчик на точной строке, которая вызывает проблему. Использование этой функции сохраняет Вас изрядное количество времени каждый день .

В C# это возможно (и я рекомендую его искренне), особенно после того, как они добавили методы TryParse ко всем классам числа. В целом ни одна из стандартных библиотек не требует или использует "плохую" обработку исключений. Когда я приближаюсь к кодовой базе C#, которая не была записана в этот стандарт, я всегда заканчиваю тем, что преобразовал его в exception-free-for-regular случаи, потому что stop-om-throw так ценен.

В отладчике JavaScript поджигателя можно также сделать это, при условии, что библиотеки не используют исключения плохо.

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

8
ответ дан krosenvold 26 November 2019 в 18:47
поделиться

Пользователь, вводящий 'плохой' вход, не является исключением: это должно ожидаться.

Исключения не должны использоваться для нормального потока управления.

В прошлом многие авторы сказали, что Исключения являются по сути дорогими. Jon Skeet вел блог вопреки этому (и упомянул некоторых время в ответах здесь на ТАК), говоря, что они не являются столь дорогими, как сообщаемый (хотя я wouldn’t рекомендую использовать их в жестком цикле!)

самой большой причиной использовать их является ‘statement intent’ т.е. если Вы видите, что обработка исключений заблокировать Вас сразу видит исключительные случаи, с которыми имеют дело за пределами нормального потока.

21
ответ дан Mitch Wheat 26 November 2019 в 18:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: