Чи повинен сервер бути “поблажливішим” у тому, що він приймає, і “мовчки відкинути несправний вхід”?


27

У мене було враження, що до цього часу всі згодні, що ця сентенція була помилкою. Але я нещодавно побачив цю відповідь, яка викликала коментар "бути поблажливим" 137 разів (станом на сьогодні).

На мою думку, поблажливість того, що браузери приймають, була прямою причиною повного безладу, що HTML та деякі інші веб-стандарти були кілька років тому, і лише нещодавно почали належним чином викристалізовуватися з цього безладу. Те, як я це бачу, бути поблажливим у тому, що ви приймаєте , призведе до цього.

Друга частина максиму - "мовчки відкинути несправне введення, не повертаючи повідомлення про помилку, якщо цього не вимагає специфікація" , і це відчуває образливі межі. Будь-який програміст, який ударив головою об стіну, коли щось мовчки не вдається, буде знати, що я маю на увазі.

Отже, я цілком помиляюся з цього приводу? Чи повинна моя програма бути поблажливішою у тому, що вона приймає та мовчить помилки? Або я неправильно трактую, що це повинно означати?


У первинному запитанні було сказано "програма", і я вважаю, що з цього приводу всі. Програми можуть мати сенс поблажливішими. Що я насправді мав на увазі, це API: інтерфейси, піддані іншим програмам , а не людям. HTTP - приклад. Протокол - це інтерфейс, який використовують лише інші програми. Люди ніколи безпосередньо не вказують дати, які переходять у заголовки типу "If-Modified-Since".

Отже, питання: чи повинен сервер, що реалізує стандарт, бути поблажливішим та допускати дати в декількох інших форматах, крім того, який фактично вимагає стандарт? Я вважаю, що "бути поблажливішим" має стосуватися цієї ситуації, а не людських інтерфейсів.

Якщо сервер поблажливий, це може здатися загальним поліпшенням, але я думаю, що на практиці це призводить лише до впровадження клієнтів, які в кінцевому підсумку покладаються на поблажливість і, таким чином, не в змозі працювати з іншим сервером, який поблажливий дещо іншими способами.

Отже, чи повинен сервер, що відкриває якийсь API, поблажливіший чи це дуже погана ідея?


Тепер поблажливіше керувати введеннями користувачів. Розглянемо YouTrack (програмне забезпечення для відстеження помилок). Він використовує мову для введення тексту, що нагадує Markdown. За винятком того, що це "поблажливіше". Наприклад, писати

- foo
- bar
- baz

це НЕ документований спосіб створення маркованого списку, і все це працювало. Отже, це в кінцевому підсумку багато використовувалося в усьому нашому внутрішньому винищувачі. Виходить наступна версія, і ця поблажлива функція починає працювати трохи інакше, порушуючи купу списків, які (помилково) використовували цю (не) функцію. Зрозуміло, документально підтверджений спосіб створення списків з маркованими списками все ще працює.

Отже, чи повинно моє програмне забезпечення бути поблажливішим щодо того, які входи користувача він приймає?


4
Щодо "мовчки відкинути несправний вхід", я б просив для кожного випадку, що слід вважати несправним введенням. Якщо ви задаєте користувачеві запитання і очікуєте, що "так" чи "ні", чи не так "ТАК" вхід? Як щодо "у"? Як щодо "oui"? Взагалі, не соромтеся сказати користувачеві, що їх введення не те, що ви очікуєте. Однак переконайтеся, що ви були максимально привабливими - на мою думку, саме так розуміється "бути поблажливішим".

3
Якщо ви говорите про введення кінцевого користувача - що стосується друзів користувачів вашої програми, то ви повинні бути уважними; для автоматизованого машинного генерованого введення (від API) ви повинні бути багатослівним (суворим).
Бурхан Халід

2
Насправді поблажливість HTML була причиною того, що він став настільки популярним (а суворість XHTML чому його скинули).
Олівер Вайлер

1
Я думаю, що головне в тому, що якщо це сценарій, коли ви можете дозволити йому вийти з ладу, це те, що ви принаймні реєструєте подію.
Риг

2
@OliverWeiler Я вважаю, що збій XHTML мав щось спільне з тим, що він був абсолютно непотрібним. HTML вже був там і свого роду працював. Крім того, хоча HTML, звичайно, надзвичайно популярний, це сумно, що ми називаємо цю технологію успішною. Він задовольняє попит, але це робить так само, як і Symbian, задовольнивши попит на смартфони.
Роман Старков

Відповіді:


9

Звичайно, ви абсолютно праві. Програми ніколи не повинні бути "поблажливішими", оскільки це служить лише для маскування проблем. Проблеми слід висвітлювати, а не підмітати під килим. Інформаційне повідомлення про помилку - це абсолютна необхідність, щоб програма була корисною для користувача.

Більшість випадків, коли надаються невірні / недійсні дані, постачальник цих даних (будь то користувач чи вихід якоїсь іншої програми), ймовірно, не знав, що це недійсні. Поглинання помилки дозволить їм переконатися, що вона (або може бути) дійсна, що поширює недійсні дані.

Єдиний спосіб взаємодії систем полягає в тому, щоб ця взаємодія була повністю визначена і однозначно визначена. Програма, яка приймає дані за межами специфікації, робить ці фактично прийнятими навіть у тому випадку, якщо специфікація недійсна, що не тільки робить сумісність величезним навантаженням важче, але й означає, що вона вже формально не визначена. Сама програма тепер є де-факто стандартом. Таким чином, поблажливіші програми неможливо розвивати далі або замінювати, оскільки ви не можете внести найменші зміни в спосіб його функціонування.


25

Я думаю, що все залежить від того, хто ваша цільова демографічна група. Якщо це програмісти, то абсолютно ні. Ваша програма повинна невдало зіткнутися і кричати криваве вбивство. Однак якщо ваша цільова аудиторія не є програмістами, тоді ваша програма повинна бути поблажливішою, де вона може витончено поводитися з винятками, інакше прошепотіть солодке криваве вбивство.

В якості прикладу візьміть програвач NPAPI Flash. Існує версія "випуску" для тих, кому не дуже важливо 99% помилок, які можуть трапитися, але є також "налагоджена" версія, яка кричить криваве вбивство, коли щось піде не так. Кожна підтримка, яка відтворює Flash-вміст, очевидно, але націлена на дві абсолютно різні демографії.

Зрештою, я вважаю, що найважливіше: що вас хвилює користувачів?


4
Переважна більшість інструментів командного рядка Unixy, які стверджують, що є цільовою аудиторією поза програмістами, тим не менш марні для користувачів, які роблять помилки. Навіть якщо ви не програміст, програмі зазвичай краще пояснити проблему, ніж робити щось безглуздо або ненавмисно.
Тімві

2
@romkyns: Не повністю, я кажу, що ваша програма повинна обробляти помилки способами, які мають сенс для ваших цільових користувачів.
Дем'ян Брехт

@Timwi: У такому випадку ці інструменти командного рядка Unixy погано зосереджені;)
Деміан Брехт

3
@romkyns - Я думаю, що хорошим прикладом може бути: У режимі налагодження ви хочете, щоб програма зупинилася на будь-яких проблемах і сказала вам, що пішло не так. У виробничому режимі ви хочете, щоб ваша програма продовжувала працювати так добре, як вона може, і реєструвати будь-які проблеми, з якими вона може впоратися. Таким чином, програмісти можуть бачити, що вони зробили не так, і виправити це, але користувачі не будуть перейматися речами, які вони не можуть виправити. Деякі проблеми, очевидно, неможливо виправити, але хорошим прикладом є правила стилю CSS, де ви все одно можете візуалізувати сайт, навіть якщо ви не розумієте жодне із правил стилю.
Відновіть Моніку

1
@ Коментар BrendanLong в значній мірі вражає цвях по голові - іноді отримання результату важливіше, ніж правильність. Деякі помилки (або попередження) можна вишукано виправити без введення користувачем; Ви самі вирішуєте, що Ви хочете робити у Вашій заяві.
Даніель Б

7

Існує два типи "поблажливіших": один - прийняти неправильний ввід і спробувати зрозуміти його, а другий - прийняти різні типи введення.

Як правило, ти завжди хочеш другого, коли це можливо. Перший - це коли ти помираєш швидко і важко. Приклад: Дати.

Ось декілька прикладів даних, включаючи дійсні, недійсні та неоднозначні.

  • 2011-01-02
  • 01/02/2011
  • Jan 2, 2011
  • 2-Jan-2011
  • Green

Там тільки один невірний введення тут: Green. Навіть не намагайтеся сприймати це як побачення. Оскільки Greenце, очевидно, не дата, це випадок, коли мовчазні відмови прийнятні.

01/02/2011є дійсним, але неоднозначним. Ви не обов'язково знаєте, введено це як дату в США (2 січня) чи ні (1 лютого). Тут, мабуть, найкраще голосно відмовитись і попросити користувача однозначно побачити.

2011-01-02Зазвичай вважається однозначним, тому часто чудово йти вперед і припускати, що це формат "РРРР-ММ-ДД", і лише провалитися далі за лінією. Хоча це і є дещо викликом судження, коли ви маєте справу з введенням користувача.

Jan 2, 2011і 2-Jan-2011є дійсними та однозначними, їх слід прийняти. Однак, такожThe Second of January of the year 2011 є дійсним та однозначним, але робити це далеко заради поблажливості є надмірним. Йти вперед і промовчати це мовчки, як і раніше .Green

Коротше кажучи , відповідь "це залежить". Погляньте на те, що можна ввести, і переконайтеся, що ви ніколи не приймаєте суперечливі типи вводу (наприклад, DD/MM/YYYYпроти MM/DD/YYYY).

У контексті пов'язаного питання / коментаря , це справа 2011-01-02. Вхід схожий на JSON і буде підтверджений як JSON, навіть якщо міметик неправильний; ідіть вперед і спробуйте використовувати його, навіть якщо він не вдається в якийсь момент далі вниз по лінії.


1
Тут є одне, про що ти не розглядаєш. Якщо користувач набрав цей рядок, то так, я повинен приймати різні формати, в цьому немає сумнівів. Але ми говоримо про API. Клієнтами API є інші програми. Якщо вона буде поблажливішою у своєму форматі дати, кожен майбутній сервер, що відкриває цей API, повинен буде бути таким же поблажливим або ризикувати несумісністю. Помилковість в кінцевому підсумку є згубною, а не корисною, ви не думаєте?
Роман Старков

1
@romkyns Я думаю, ви нерозумієте, де лежить поблажливість. API повинен бути поблажливим в тому, що він приймає (він повинен розуміти все 2011-01-02, Jan 2, 2011і 2-Jan-2011, якщо це не дуже складно реалізувати), а не в тому, що вона виводить . Майбутнім клієнтам цього API навіть не потрібно знати про якийсь даний, якщо вони правильно вводять один з них. В ідеалі рівень API перетворив би все це в те саме внутрішнє представлення, яке використовує код, перш ніж передавати його уздовж.
Ізката

Наприклад, вихід @romkyns міг завжди бути у 2011-01-02форматі, і це той, який ви вкладете у свою документацію. Я взагалі не бачу згубного ефекту.
Ізката

4
@Izkata: Ви неправильно зрозуміли. Уявіть, що там була стара програма, яка доступна лише як двійкова. Ви повинні написати нову програму, яка приймає ті ж входи, що і стара. Якщо стара програма була чітко визначена в тому, що вона приймає, ваша робота чітко визначена. Якщо вона поблажливіша, то ваша робота неможлива.
Тімві

1
Категорично не згоден. якщо це не введений користувачем вхід, завжди будьте суворими як введеннями, так і вихідними. Що відбувається, коли вашу послугу потрібно повторно впровадити? Ви документували всі можливі формати дати? Вам потрібно буде впровадити їх усі, оскільки ви не хочете, щоб старі клієнти ламалися. Будь ласка, використовуйте ISO 8601 для всіх випадків та періодів, створених машиною: він чітко визначений і широко доступний у бібліотеках. До речі, що насправді означає 2011-01-02? Проміжок часу з 00:00 2-го до 00:00 3-го? У якому часовому поясі?
Діббеке

6

Невдача мовчки - це найгірше, що ви могли зробити коли-небудь. Ви намагалися налагодити API з тихою помилкою? Це неможливо .

Там є "Зробіть все можливе, щоб відновити, але надішліть детальну помилку" і є "Мовчазний збій".


3

Мені здається, що Закон Постела - "Будьте консервативними у тому, що ви робите, будьте ліберальні у тому, що приймаєте від інших", - це те, що обговорюється для служби JSON. Зазвичай це стосується веб-служб, а не інтерфейсу користувача.

Для конструктивного зворотного зв’язку користувачів та інтерфейсу користувача, що скорочує користувача, є основним правилом, яке ми використовуємо.


Але якщо поглянути на відповіді тут, то, схоже, всі погоджуються, що це має сенс для користувальницьких інтерфейсів, тобто навпаки початкового закону.
Роман Старков

Я бачу, що ви говорите, і погоджуюся з плакатами, що мета чистого API / послуги є ціллю, але на краще або гірше я знаю, що я додала "надійності" в тій чи іншій формі до моїх служб. Зазвичай переклад значення або два на дні. Поки сенс зрозумілий, додаток знає, як обробити повідомлення, і жодні правила бізнесу не порушуються, тоді додавання надійності допоможе сумісності.
MarcLawrence

Поки хтось інший не піде і не реалізує вашу специфікацію, лише щоб з'ясувати, що "надійність", на яку сотні клієнтів покладаються на неї, насправді не було в специфікації і має бути реверсивним ...
Роман Старков

3

Я думаю, що це добре висвітлено у розділі 6 розділу ТАОУП 1. Зокрема, правило ремонту , в якому йдеться про те, що програма повинна робити все, що може, із входом, передавати правильні дані вперед, а якщо правильна реакція - це невдача, зробіть це як можна швидше.

Подібна концепція - оборонне програмування . Ви не знаєте, який саме внесок ви отримаєте, але ваша програма повинна бути достатньо надійною, щоб охопити всі випадки. Це означає, що слід запрограмувати у випадках відновлення для відомих проблем, таких як непрацюючий вхід, і виправити всі випадки, щоб обробити невідомі.

Так відкидаючи несправний вхід беззвучно нормально, так довго , як ви будете обробками , що введення. Ніколи не слід просто опускати його на підлогу, як це було.


Для API я вважаю, що поблажливість - це те саме, що і для програми. Введення все ще неправильне , але ви намагаєтесь якнайкраще відремонтувати. Різниця полягає в тому, що вважається дійсним ремонтом . Як ви зазначаєте, поблажливіший API може спричинити проблеми, оскільки люди використовують "функції", які не існують.

Звичайно, API - це лише версія нижчого рівня правила композиції . Як такий, він дійсно охоплюється правилом найменшого сюрпризу , оскільки це інтерфейс.

Як зазначає цитата зі Спенсера, уникайте поверхневої подібності, про яку можна сперечатися з приводу "нечітких" даних. За цих умов я зазвичай стверджую, що все вказує на неможливість відновлення програми, оскільки вона не буде знати, що потрібно, і це найменше дивно для користувальницької бази.

Однак ви маєте справу з датами, які мають багато "стандартів". Іноді вони навіть змішуються в одній програмі (ланцюжку). Оскільки ви знаєте, що очікується побачення, спроба визначити дату - це лише хороший дизайн. Особливо, якщо дата надходить із якоїсь зовнішньої програми і передається немодифікованою через секунду на шляху до вас.


2

Програми, які більшу частину часу розгортаються на сервері, повинні приймати тисячі запитів щохвилини, а іноді і щосекунди. Якщо серверна програма приймає та виправляє несправні дані від клієнтів, я боюся, у неї будуть два недоліки:

  1. Втрата дорогоцінного часу сервера. З 1000+ запитами в секунду перевірка на наявність помилок у кожному запиті може відображатися у повільній відповіді для кожного клієнта.
  2. Недобросовісне відношення до клієнта / клієнтських програм, які забезпечують правильне введення даних. Крім цього, коли програміст на стороні сервера сидить за кодом сервера, він / вона повинен думати про різні випадки того, які можуть бути несправні входи. Хто це вирішить?

Серверні програми не повинні приймати несправне введення, але сервери повинні повернути клієнтові повідомлення про помилку, якщо є несправний ввід.


2

Ідеальна поведінка, концептуально, полягає в тому, щоб робити те, що можна зробити безпечно, одночасно забезпечуючи, щоб хтось, хто може виправити будь-які проблеми, якось повідомлявся про них. На практиці, звичайно, останнє обмеження часто неможливо безпосередньо зустріти, і тому питання стає найкращим для вирішення сумнівних даних.

Одне, що може бути дуже корисним при розробці протоколу, специфікації форматування або "мови", - це наявність засобів для виділення чотирьох категорій потенційних незрозумілих елементів:

  1. Речі, які слід відфільтрувати, якщо їх не зрозуміти.
  2. Речі, які слід ігнорувати, якщо їх не розуміють, але тим не менше зберігають, якщо дані потрібно передавати (можливо, в якомусь обгортці, щоб вказати, що він пройшов хоча б один етап, який не зрозумів його)
  3. Речі, які повинні генерувати попередження, якщо їх не розуміють, але не повинні перешкоджати спробі відновлення даних (наприклад, на веб-сторінці, об’єкт, тип якого невідомий, але кінець у файлі чітко визначений, може бути відображений як червоний "X", не перешкоджаючи візуалізації решти сторінки.)
  4. Речі, які вказували б на те, що все, що їх не може зрозуміти, може мати серйозні та нерозв’язувані проблеми в інших місцях (наприклад, показник стиснення решти даних та що-небудь, що було б зрозуміло будь-що, що могло б виконати необхідне стискання).

Наявність чітко визначеної конвенції, за допомогою якої програми, які можуть читати будь-яку версію формату даних, зможуть розпізнати, яка категорія підходить для всього, що генерується відповідно до пізніших версій, є набагато кращим підходом, ніж спроба вклинитися в спеціальні заходи сумісності в подальшому. Наприклад, якщо у форматі файлу є рядки форми "Тег: Значення", можна вказати, що перший символ будь-якого тегу буде вказувати категорію, до якої він належить; для тегів категорій беззвучного ігнорування можна було б, щоб перший символ також вказував версію стандарту, для якого, як очікується, тег буде дійсним (так що, якщо тег "мовчання-ігнорування" претендує на присутність у версії 3 стандарт, аналізатор версії мовчки проігнорує його, але аналізатор версії 3 або пізнішої вершини блукав, якщо він не міг би його розібрати).

Найголовніше в будь-якому випадку - уникати перетворення неоднозначних чи неправильно зрозумілих даних у помилкові дані. В деяких випадках може бути краще взагалі відмовитись від поширення неоднозначних даних, хоча в інших випадках може бути краще поширити їх точно так, як отримано, якщо одержувач вважатиме це однозначним. По-справжньому небезпечним, якщо не відвертим злом, є перетворення даних за допомогою різних припущень, наприклад перетворення списку дат, таких як:

12.01.12
13/12/12
99/12/12

у список таких дат, як

2012-01-12
2012-12-13
1999-12-12

Навіть якщо у вас був список з кількома помилково вписаними датами, людина може отримати список в оригінальному форматі, щоб визначити, який формат був правильним, і позначити сумнівні значення для подальшого дослідження (перевірка проти інших записів тощо). ) Однак подання дат в останньому форматі, безнадійно і безповоротно їх не дасть.


Добре сказано. Мені подобається, як ваша відповідь трохи глибша. Я спокушаюсь прийняти це, але враховуючи загальний інтерес, який отримав це питання, я думаю, що я залишу це на деякий час.
Роман Старков

1

Мій досвід користувальницького інтерфейсу здебільшого відбувається з настільних систем. Веб-сайти різні, хоча я бачив кілька сайтів, які можуть кинути виклик настільній системі. Але для чого це варто:

Я виявив, що повідомлення про помилки мають бути самим крайнім засобом; ідеальна система взагалі не мала б їх. Найкраще зробити це - не допускати в першу чергу поганих записів: користувач не може ввести "зелений", якщо він вибирається зі спадного списку місяців. Він не може натиснути сіру кнопку.

Наступне найкраще, що потрібно зробити - це прийняти погані дані. Скажімо, ви показуєте гістограму щоденних продажів протягом місяця. Після введення користувачем графік охоплює століття, а смужка на століття більше - в 10 разів вище, ніж інші. Користувач тепер знає, що він зробив щось не так, і, тим більше, знає набагато більше про те, що він зробив неправильно, ніж будь-яке повідомлення може сказати йому. Якщо запис є графічним - наприклад, перетягуванням миші - такий тип зворотного зв'язку все ще працює і є безцінним. Купа даних може бути недійсною, але, використовуючи цей метод, користувач отримує миттєвий, детальний відгук про результати кожної позиції миші.

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


0

У заяві йдеться про надсилання інформації через Інтернет. Однією з речей, що надсилають інформацію через Інтернет, є те, що не завжди вона взагалі потраплятиме до цілі або її фрагментарно.


0

Щось, що, здається, тут пропущено - які наслідки невдачі?

Показати веб-сторінку? Ви повинні зробити все можливе, щоб терпіти поганий внесок. Ваш вибір полягає у відображенні того, що ви можете, або помилці. Останній курс не дає користувачеві нічого, і тому він повинен бути лише в крайньому випадку, оскільки він дає користувачеві абсолютно марний результат, було б досить важко, щоб помилка була гіршою за цю.

З іншого боку, якщо ви просите ціль Мінутемана III, ви відхиляєте "Москву" як вхід, оскільки це потенційно неоднозначно.


Тож навіть якщо ви програміст, і ви написали якийсь дурний код, система повинна йти вперед і робити все можливе, щоб щось показати, а не просто зупинятися і кричати "ой, ти тут накрутив (номер рядка)"? Ви не думаєте, що саме це призводить до неймовірно поганого коду?
Роман Старков

@romkyns: у вас є режими налагодження для подібних речей, які суворо ставляться до хитання з приводу помилок.
Лорен Печтел
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.