Ръководство за начинаещи за смачкване на грешки: Как да използвате вашия дебъгер и други инструменти за намиране и отстраняване на грешки

Като уеб разработчици често ни се струва, че отделяме повече време за поправяне на грешки и опити за решаване на проблеми, отколкото за писане на код. В това ръководство ще разгледаме някои често срещани техники за отстраняване на грешки, така че нека да заседнем.

„Не се подготвям, подготвям се да се проваля“

Какъв по-добър начин да започнете статия, отколкото със старо клише! Грешки и проблеми ще изскачат. Просто няма начин да се измъкнем от това (извинете). С едно просто планиране има начини, по които можем да сведем до минимум сложността и броя на проблемите, с които се сблъскваме.

Разделете задачата на по-малки задачи

Сега разбирам, всички обичаме да се вълнуваме много и да се потопим направо в нашите проекти за кодиране. Работата е там, че без някакъв план си създаваме проблеми, преди дори да започнем!

Ако ви кажа „трябва да създадете приложение за списък за пазаруване“ и започнете да кодирате веднага, какво ще се случи? В крайна сметка ще се взирате в мигащ курсор, чудейки се как или какво да направите първо, проклинайки името ми под нос, за да ви помоля да направите такава задача.

Винаги е по-лесно да вземете голям проблем и да го разделите на много по-малки проблеми. Например можем да разделим проекта за списък за пазаруване на по-малки задачи:

  • Създайте формуляр, за да добавите елемент към списъка
  • Позволете на потребителя да премахне елемент от списъка
  • Показване на общия брой елементи в списъка

Можете дори да разделите тези задачи на по-подробни задачи. Например, за първата задача в нашия списък, нашата първа, „малка мини задача“ (трябва ли да запазя марката на този термин?) Може да бъде:

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();

Грешката, хвърлена в браузъра, ще ви покаже проблема по-бързо, но не всички проекти за интерфейс ще бъдат конфигурирани да правят това, а разработчиците на бекенда нямат този лукс. Ето защо препоръчвам да се научите да четете проследяването на стека.

За да победите грешката, трябва да мислите като грешката

Проследяването на стека ви дава представа каква е грешката. Е, понякога става, а понякога не. Какво ще стане, ако видите съобщение за грешка, което прилича повече на пещерни глифи, отколкото на английски? Или какво ще стане, ако няма грешка, но вашият код просто не действа както сте си помислили?

Време е да извадите дебъгера. Нека да разгледаме друг пример. Но първо някакъв контекст!

Г-н Боб CEO (който е изпълнителен директор, кой би помислил ?!) се приближава до вас и казва,

„Хей, имам невероятна идея за продукт.

  • Искам уеб приложение, което позволява на потребителя да въведе номер.
  • Ако номерът е по-малък от 5, съобщението трябва да гласи "ПОД".
  • Ако броят е равен или по-голям от 5, съобщението трябва да гласи "НАД".

Това е идея за милиони долари и искам да я изградите за мен ".

"ДОБРЕ!" Казваш и се захващаш за работа.

* Монтаж на кодиране с драматична музика се възпроизвежда с напредване напред

Попълнихте кода за вашето уеб приложение. Хуза!

    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 }); })(); 

(Забележка: Може би вече сте забелязали грешката. Ако сте я направили, нека се преструваме, че не сте я направили. Ако не сте забелязали грешката, това е добре.)

Време е да започнете да тествате. Нека разгледаме някои случаи на употреба за нашата бизнес логика.

1) Потребителят въвежда 3:

2) Потребителят въвежда 7

Дотук добре! Но какво ще стане, ако въведем 5?

О, НЕ! Буболечка! Показваният текст е неправилен, той трябва да показва „ OVER “, но вместо това показва „ UNDER “. Хм, няма съобщения за грешка,и не мога да видя в кода какво не е наред. Нека да стартираме дебъгъра и да преминем през кода.

Използване на дебъгера

Добро място да започнете е да поставите точката на прекъсване възможно най-близо до бъги кода. Можете да определите това, като прочетете кода, съобщенията за грешки или ако имате този момент „ а-ха! Знам кой метод причинява този “. Оттук нататък става въпрос за преминаване през кода, проверка на променливите и проверка дали се изпълняват правилните клонове на кода.

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 :)