|
| 1 | +# Швидко відмовляйте, валідуйте аргументи за допомогою спеціальної бібліотеки |
| 2 | + |
| 3 | +### Пояснення за один абзац |
| 4 | + |
| 5 | +Ми всі знаємо, наскільки важливо перевіряти аргументи та швидко відмовляти, щоб уникнути прихованих помилок (дивіться приклад коду антипатерну нижче). Якщо ні, прочитайте про експліцитне програмування та оборонне програмування. Насправді ми часто уникаємо цього через незручності кодування (наприклад, подумайте про валідацію ієрархічного JSON-об'єкта з полями, як-от email та дати) – бібліотеки на кшталт Joi та Validator перетворюють це нудне завдання на легкий процес. |
| 6 | + |
| 7 | +### Вікіпедія: Оборонне Програмування |
| 8 | + |
| 9 | +Оборонне програмування - це підхід до покращення програмного забезпечення та вихідного коду з точки зору загальної якості - зменшення кількості програмних помилок та проблем. Роблення вихідного коду зрозумілим - вихідний код має бути читабельним і зрозумілим, тому він має бути схвалений при аудиті коду. Призводить програмне забезпечення до прогнозованої поведінки, незважаючи на непередбачені входи чи дії користувача. |
| 10 | + |
| 11 | +### Приклад коду: валідація складного JSON введення за допомогою ‘Joi’ |
| 12 | + |
| 13 | +```javascript |
| 14 | +const memberSchema = Joi.object().keys({ |
| 15 | + password: Joi.string().regex(/^[a-zA-Z0-9]{3,30}$/), |
| 16 | + birthyear: Joi.number().integer().min(1900).max(2013), |
| 17 | + email: Joi.string().email() |
| 18 | +}); |
| 19 | + |
| 20 | +function addNewMember(newMember) { |
| 21 | + // перші з'являються переконання |
| 22 | + Joi.assert(newMember, memberSchema); // кидає помилку, якщо валідація не пройшла |
| 23 | + // тут інша логіка |
| 24 | +} |
| 25 | +``` |
| 26 | + |
| 27 | +### Антипатерн: без валідації з'являються неприємні помилки |
| 28 | + |
| 29 | +<details> |
| 30 | +<summary><strong>Javascript</strong></summary> |
| 31 | + |
| 32 | +```javascript |
| 33 | +// якщо знижка позитивна, тоді перенаправимо користувача роздрукувати його купони на знижку |
| 34 | +function redirectToPrintDiscount(httpResponse, member, discount) { |
| 35 | + if (discount != 0) { |
| 36 | + httpResponse.redirect(`/discountPrintView/${member.id}`); |
| 37 | + } |
| 38 | +} |
| 39 | + |
| 40 | +redirectToPrintDiscount(httpResponse, someMember); |
| 41 | +// забули передати параметр знижки, чому, біса, користувач був перенаправлений на екран зі знижкою? |
| 42 | +``` |
| 43 | +</details> |
| 44 | + |
| 45 | +<details> |
| 46 | +<summary><strong>Typescript</strong></summary> |
| 47 | + |
| 48 | +```typescript |
| 49 | +// якщо знижка позитивна, тоді перенаправимо користувача роздрукувати його купони на знижку |
| 50 | +function redirectToPrintDiscount(httpResponse: Response, member: Member, discount: number) { |
| 51 | + if (discount != 0) { |
| 52 | + httpResponse.redirect(`/discountPrintView/${member.id}`); |
| 53 | + } |
| 54 | +} |
| 55 | + |
| 56 | +redirectToPrintDiscount(httpResponse, someMember, -12); |
| 57 | +// Ми передали негативний параметр знижки, чому, біса, користувач був перенаправлений на екран зі знижкою? |
| 58 | +``` |
| 59 | +</details> |
| 60 | + |
| 61 | +### Цитата з блогу: "Слід кидати ці помилки негайно" |
| 62 | + |
| 63 | +З блогу: Joyent |
| 64 | + |
| 65 | +> Дегенеративний випадок - це коли хтось викликає асинхронну функцію, але не передає зворотний виклик. Ці помилки слід кидати негайно, оскільки програма зламана і найкращий шанс налагодити її включає отримання принаймні трасування стеку і в ідеалі основного файлу в місці помилки. Для цього ми рекомендуємо проводити валідацію типів всіх аргументів на початку функції. |
0 commit comments