Co mówią cztery części komunikatu i od której linii czytać
Trzy rodziny błędów: składnia, działanie, logika
Ćwiczenie: trzy programy, trzy błędy do znalezienia
Rozgrzewka · 3 minuty
Z poprzedniej lekcji: dane od użytkownika
Czym w każdym z tych trzech języków pobieramy dane od użytkownika?
Dlaczego to, co wpisze użytkownik, trzeba najpierw zamienić na liczbę?
Jak wstawiamy wartość zmiennej w środek napisu?
Część 1 · Gdzie szukać
Komunikat gdzieś jest. Trzeba wiedzieć gdzie
php.net: Language Reference › Errors › Basics · docs.python.org: tutorial 8.1 „Syntax Errors” · MDN: Learn_web_development/Core/Scripting/What_went_wrong (sekcja „Fixing errors reported in the console”)
Część 1 · Anatomia komunikatu
Cztery części jednego komunikatu
Kolejność pracy: otwórz podany plik, przejdź do podanej linii, a jeśli w niej nic nie widać, spójrz na linię wyżej. Tam najczęściej brakuje średnika, nawiasu albo dwukropka.
Błąd logiczny wygląda tak: program ma odjąć 10 % rabatu od ceny 120, a w kodzie stoi $total = $price * 0.1;. PHP wypisuje Razem: 12 i kończy pracę bez jednego ostrzeżenia. Powinno wyjść 108.
docs.python.org: tutorial 8.1 „Syntax Errors” i 8.2 „Exceptions” · php.net: Language Reference › Errors › Basics · MDN: Learn_web_development/Core/Scripting/What_went_wrong (sekcja „Types of error”)
Część 2 · Błąd składni
Program nie rusza: błąd składni
PHP · price.php
<?php
$price = 120
echo $price;
Parse error: syntax error,
unexpected token "echo"
in price.php on line 3
Python · price.py
price = 120
if price > 100
print("Rabat")
File "price.py", line 2
if price > 100
^
SyntaxError: expected ':'
JavaScript · script.js
let price = 120;
for (let i = 1; i <= 3; i++) {
console.log(i);
script.js:4
Uncaught SyntaxError:
Unexpected end of input
Wszystkie trzy komunikaty wskazują linię po tej, w której coś zginęło: brak średnika, brak dwukropka, brak klamry zamykającej. Dlatego po wejściu we wskazaną linię zawsze sprawdzamy też linię wyżej.
Warning: Undefined variable
$total in total.php on line 3
Razem:
Python · total.py
price = 120
print("Razem:", total)
Traceback (most recent call last):
File "total.py", line 2
print("Razem:", total)
^^^^^
NameError: name 'total' is
not defined
JavaScript · script.js
let price = 120;
let discount = 10;
console.log("Razem: " + total);
Uncaught ReferenceError:
total is not defined
at script.js:3:25
Dzielenie przez zero, ta sama linia 100 / 0: PHP przerywa program błędem DivisionByZeroError, Python błędem ZeroDivisionError, a JavaScript spokojnie wypisuje Infinity i pracuje dalej.
text = "abc"
try:
number = int(text)
print(100 / number)
except ValueError:
print("To nie jest liczba")
except ZeroDivisionError:
print("Brak wyniku")
Wypisuje: „To nie jest liczba”
JavaScript
const text = "abc";
try {
const number = Number(text);
if (Number.isNaN(number))
throw new Error("To nie jest liczba");
console.log(100 / number);
} catch (e) {
console.log("Brak wyniku: " + e.message);
}
Wypisuje: „Brak wyniku: To nie jest liczba”
Ten sam napis "abc", trzy różne momenty wykrycia: Python zgłasza błąd już przy zamianie na liczbę, PHP dopiero przy dzieleniu, a JavaScript nie zgłasza go wcale, więc programista sprawdza wynik sam i zgłasza błąd słowem throw.
Traceback (most recent call last):
File "discount.py", line 3
final_price = price - discunt
^^^^^^^
NameError: name 'discunt' is not
defined. Did you mean: 'discount'?
C · script.js
let items = [3, 5, 2];
let total = 0;
for (let i = 0; i < items.length; i++) {
total = total + items[i];
console.log("Razem: " + total);
script.js:6
Uncaught SyntaxError:
Unexpected end of input
Dla każdego programu zapisz trzy rzeczy: numer linii z prawdziwym błędem, rodzaj błędu (składnia albo w trakcie działania) i poprawkę.
Program A w PHP
Program B w Pythonie
Program C w JavaScripcie
Sprawdzenie
Trzy pytania na koniec
Gdzie zobaczycie błąd programu napisanego w JavaScripcie?
Która rodzina błędów nie daje żadnego komunikatu?
Od której linii czyta się komunikat w Pythonie?
Podsumowanie
A jak to wygląda w produkcji?
Na lekcji
W produkcji
Status
Komunikat na stronie
Wyłączony dla gości, bo zdradza ścieżki plików. Trafia do dziennika serwera
standard
Szukanie błędu po komunikacie
Systemy, które zbierają błędy z serwera i z przeglądarek wszystkich użytkowników
codziennie
try i catch
Każde sięgnięcie do bazy, pliku albo sieci ma obsługę błędu, bo sieć bywa zerwana
codziennie
Błąd logiczny
Łapią go testy i przegląd kodu przez drugą osobę, bo komunikatu nie będzie
standard
Ciekawostka: PHP ma funkcję fdiv(), która dzieli dokładnie tak jak JavaScript: zamiast przerwać program zwraca INF. Jeden język potrafi więc zachować się na oba sposoby, zależnie od tego, którego zapisu użyjecie.
ciekawostka: php.net: Function Reference › Math › fdiv · MDN: Web/JavaScript/Reference/Global_Objects/Infinity