Посібник для початківців зі знищення помилок: Як використовувати свій налагоджувач та інші інструменти для пошуку та виправлення помилок

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

"Не вдалося підготуватися, підготуватися до невдачі"

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

Розбийте завдання на менші завдання

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

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

Завжди легше взяти велику проблему і розбити її на багато менших проблем. Наприклад, ми можемо розбити проект списку покупок на менші завдання:

  • Створіть форму, щоб додати елемент до списку
  • Дозволити користувачеві вилучати елемент зі списку
  • Відображення загальної кількості елементів у списку

Ви навіть можете розбити ці завдання на більш детальні. Наприклад, для першого завдання в нашому списку, нашим першим, «маленьким міні-завданням» (чи слід мені використовувати цей термін?) Може бути:

1) Створіть поле введення для фіксації назви елемента

2) Створіть кнопку, яка викликає функції addToList()при натисканні

3) Напишіть логіку у addToList()функції, яка додає елемент до списку

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

Будьте готові очистити свій код

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

Б'юсь об заклад, ти думаєш: "о, чоловіче, мені знадобилися дні / тижні / тисячоліття, щоб дійти так далеко зі своїм кодом, і тепер я повинен його видалити ?!" Так, так. Іноді. Вибачте. Реальність веб-розробки полягає в тому, що код постійно змінюватиметься з різних причин - помилок, оглядів коду, змін вимог, нудьги тощо.

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

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

Повідомлення про помилки хороші

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

Якщо ми подивимось на цей приклад:

let animals; function addAnimal(){ animals.push('elephant'); } addAnimal();

Тепер давайте подивимося на помилку:

TypeError: Cannot read property 'push' of undefined at addAnimal (//vanilla.csb.app/src/index.js:8:11) at evaluate (//vanilla.csb.app/src/index.js:11:1) at $n (//codesandbox.io/static/js/sandbox.acff3316.js:1:148704)

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

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

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

Cannot read property 'push' of undefined

Зазвичай це означає, що є змінна, яка десь не визначена чи ініціалізована. АЛЕ ДЕ?!?

Якщо ми продовжуємо читати трасування стека, ми бачимо, що помилка виникає всередині addAnimal()функції. Ми бачимо, що намагаємося підштовхнути нову тварину до масиву - ах! Я забув ініціалізувати animalsмасив. Дох! Наш фіксований код виглядає так:

let animals = []; function addAnimal() { animals.push("elephant"); } addAnimal();

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

Щоб перемогти помилку, ви повинні думати як помилка

Трасування стека дає уявлення про помилку. Ну, іноді це відбувається, а іноді ні. Що робити, якщо ви бачите повідомлення про помилку, яке більше схоже на печерні гліфи, ніж на англійську? Або що, якщо помилки немає, але ваш код просто діє не так, як ви думали?

Пора вивести налагоджувач. Давайте розглянемо ще один приклад. Але спочатку якийсь контекст!

Містер Боб (хто є генеральним директором, хто б міг подумати ?!) підходить до вас і каже:

"Гей, у мене є дивовижна ідея для продукту.

  • Я хочу веб-програму, яка дозволяє користувачеві вводити номер.
  • If the number is less than 5, the message should read "UNDER".
  • If the number is equal to or more than 5, the message should read "OVER".

This is a million-dollar idea and I want you to build it for me".

"OKAY!" You say, and you get to work.

*Coding montage with dramatic music plays as time fast forwards*

You've completed the code for your web app. Huzzah!

    My super awesome number app      Submit 0 
(function () { const numberInputSubmitButton = document.getElementById("number-input-submit-button") numberInputSubmitButton.addEventListener("click", function () { const numberInputValue = document.getElementById("number-input").value; let text; if(numberInputValue > 5) { text = "OVER"; } else { text = "UNDER"; } document.getElementById("number-display").innerHTML = text }); })(); 

(Note: You may have spotted the bug already. If you did, let's pretend you didn't. If you haven't noticed the bug, that's OK.)

Time to start testing. Let's run through some use cases for our business logic.

1) User enters 3:

2) User enters 7

So far so good! But what happens if we enter 5?

OH NO! A bug! The text displayed is incorrect, it should display "OVER" but instead displays "UNDER". Hmm, no error messages,and I can't seem to see in the code what is wrong. Let's run the debugger and step through the code.

Using the debugger

A good place to start is to put a breakpoint as close to the buggy code as possible. You can determine this by reading the code, error messages, or if you have that "ah-ha!I know which method is causing this" moment. From here, it's a case of stepping through the code, inspecting the variables, and checking if the correct code branches are run.

In our example, I have put a breakpoint at the start of my if statement - as this is where the failing logic is.

Once I start debugging, chrome opens and I can replicate the issue by entering "5" and clicking submit. This hits the breakpoint, and immediately there are a few things to note:

  • The debugger stops at the breakpoint, so this means I'm on the right track
  • This also means that the function is being called correctly, and event handlers are working as expected
  • I can also see that the user input is being captured correctly (from the "variables" panel on the left-hand side, I can see that "5" was entered)

So far so good, no immediate issues to worry about. Well, code related ones anyway. Next, I'll press F10 to step through the code. This runs each statement individually, allowing us to inspect elements, variables, and other things at our own pace. Isn't technology just fabulous?

Remember since I expect the message "OVER" to appear when the user enters "5", I'm expecting the debugger to take me into the first branch of the if statement...

BUT NO! I'm brought into the second branch. Why? I need to amend the conditional to read "more than or equals to" as opposed to "more than".

if(numberInputValue >= 5) { text = "OVER"; } else { text = "UNDER"; }

Success! Our bug is fixed. Hopefully this gives you an idea on how to walk through the code, making use of VSCodes awesome debugging tools.

More Debugging tips

  • If your breakpoints aren't being hit, this could be part of the issue. Make sure the correct functions or event handlers are being called in the way you expect
  • You can step over functions you want to skip. If you want to debug any functions you come across, use the step into command
  • Watch out for variables, parameters, and arguments as you are stepping through your code. Are the values what you expect?
  • Write code in a way that is easier to read/debug. It might look cool to have your code on one line, but it makes debugging harder

Google is your friend

Ok so we've looked at the stack-trace, tried debugging, and we're still stuck with this bug. The only thing left to do now is make a sacrifice to the coding gods and hope things fix themselves!

Or I guess we could use Google.

Google is a treasure trove of software development problems and solutions, all at our fingertips. It can be sneakily difficult to access this information though, as you have to know how to Google the right things to get the right information! So how do we effectively use Google?

Let's look back to our first example - you've read the stack trace, looked at the code, but the message Cannot read property 'push' of undefined is still driving you mad. Bewildered, you take to Google in hopes of finding an answer. Here are some things to try:

Copy and paste the error message. Sometimes this works, depending on how "generic" the error message is. For example, if you get a Null pointer exception (who doesn't love those?), Googling "Null pointer exception" might not return very helpful results.

Search for what you are trying to do. For example, "How to create an array and add an item to the end". You might find some generous developer has posted a solution using best practices on StackOverflow, for example. You might also find this solution is completely different from yours - remember what I said about being comfortable purging your code?

A side note on using someone else's code - try and avoid blindly copying and pasting, make sure you understand what the code does first!

Ask for help the right way

Hopefully, after a mix of debugging, stack trace investigating, and Googling you have seen the light at the end of the tunnel and solved your problem. Unfortunately, depending on what you are trying to do, you still might be a bit stumped. This is a good time to seek advice from other people.

Now, before you run into the street screaming "my code is broken please help me!", it's important to know the best way to ask for help. Asking for help in the right way makes it easier for people to understand the problem and help you solve it. Let's look at some examples:

Bad - "My code is broken and I don't know what's wrong."

Good - "I'm trying to add an item to the end of an array in JavaScript, and I'm getting this error message: Cannot read property 'push' of undefined. Here's my code so far."

See how the "Good" example is much more informative? More information makes it easier for other kindhearted devs to help you out. This is a good habit to get into as it not only benefits you when you are learning to code but also in your first job when you need to ask for help.

So where can you ask for help?

  • StackOverflow
  • Twitter
  • Slack groups
  • Colleagues or developer friends

Quick Tip: You can use a tool like CodeSandbox.io or CodePen.io to recreate your problem and share it with people.

Practice, practice, practice

Just like Rome wasn't built in a day (well, it could have been for all I know) you will not become king bug squasher overnight. As your career goes on and your experience grows, you'll be armed with a wealth of knowledge that helps you solve bugs and issues faster. I regularly find myself saying "ah, I've solved that before" or "oh yeah, I have a StackOverflow link that helps me here" and the whole thing becomes a lot easier. So keep practicing, and this skill will grow naturally.

Thanks for reading! If you enjoyed this article, why not subscribe to my newsletter?

Every week I send out a list of 10 things I think are worth sharing — my latest articles, tutorials, tips and interesting links for upcoming developers like you. I also give out some free stuff from time to time :)