Στη JavaScript, τα σφάλματα (ή errors) είναι ανεπιθύμητες καταστάσεις που προκύπτουν κατά την εκτέλεση του κώδικα. Αυτές οι καταστάσεις μπορεί να οφείλονται σε λάθη στον κώδικα, μη έγκυρες ενέργειες από τον χρήστη, ή άλλες ανεπιθύμητες συνθήκες που μπορεί να επηρεάσουν την εκτέλεση του προγράμματος.
Υπάρχουν διάφοροι τύποι σφαλμάτων στη JavaScript, και κάθε ένας από αυτούς μπορεί να έχει διαφορετικό αίτιο και διαχείριση:
- Συντακτικά Σφάλματα (Syntax Errors): Προκύπτουν όταν ο κώδικας δεν συμμορφώνεται με το συντακτικό της JavaScript. Τέτοια σφάλματα ανιχνεύονται από τον μεταγλωττιστή (compiler) πριν από την εκτέλεση.
- Λογικά Σφάλματα (Logical Errors): Προκύπτουν όταν ο κώδικας εκτελείται αλλά παράγει λανθασμένα αποτελέσματα. Τέτοια σφάλματα συνήθως οφείλονται σε λάθη στη λογική του προγράμματος.
- Εξαίρεση (Exception): Είναι ένα ανεπιθύμητο συμβάν ή κατάσταση που προκαλείται κατά την εκτέλεση και παραβιάζει τον σωστό ροή εκτέλεσης του προγράμματος. Οι εξαιρέσεις μπορούν να προκληθούν από λάθη του προγραμματιστή, κακή χρήση των δομών δεδομένων, μη έγκυρες εισαγωγές χρήστη κ.ά.
Για την διαχείριση των σφαλμάτων, η JavaScript παρέχει τη δομή των εξαιρέσεων (exceptions) με τη χρήση των try
, catch
, και finally
blocks. Αυτή η δομή επιτρέπει στον προγραμματιστή να “πιάσει” ένα σφάλμα, να εκτελέσει κώδικα για την αντιμετώπισή του, και να συνεχίσει την εκτέλεση του προγράμματος.
Παράδειγμα χρήσης της δομής try
–catch
:
try { // Κώδικας που μπορεί να προκαλέσει σφάλμα let result = someFunction(); } catch (error) { // Εκτελείται όταν προκύψει σφάλμα console.error("An error occurred:", error); } finally { // Εκτελείται πάντα, ανεξάρτητα από το αν υπήρξε σφάλμα ή όχι console.log("Execution completed."); }
Η δομή try
–catch
μας επιτρέπει να πιάσουμε εξαιρέσεις και να διαχειριστούμε την εκτέλεση του προγράμματος ανάλογα με το αν προκλήθηκε σφάλμα ή όχι.
[adinserter block=”2″]
Η δήλωση try
σας επιτρέπει να ορίσετε ένα τμήμα κώδικα που θα ελεγχθεί για σφάλματα κατά τη διάρκεια της εκτέλεσής του.
Η δήλωση catch
σας επιτρέπει να ορίσετε ένα τμήμα κώδικα που θα εκτελεστεί αν προκύψει ένα σφάλμα στην ενότητα try
.
Οι δηλώσεις JavaScript try
και catch
έρχονται πάντα σε ζευγάρια:
try { // Τμήμα κώδικα που ελέγχεται για σφάλματα // Αν προκύψει σφάλμα, η εκτέλεση μεταφέρεται στο τμήμα catch } catch (error) { // Τμήμα κώδικα που εκτελείται αν προκύψει σφάλμα στο τμήμα try } finally { // Τμήμα κώδικα που εκτελείται πάντα, ανεξάρτητα από το αν προκύψει σφάλμα ή όχι }
Η δομή try
–catch
μας επιτρέπει να διαχειριστούμε τα σφάλματα και να εκτελέσουμε ειδικές ενέργειες όταν προκύψουν σφάλματα, ώστε να διασφαλίζεται ότι το πρόγραμμα συνεχίζει να εκτελείται με ομαλό τρόπο.
Όταν συμβεί ένα σφάλμα, η JavaScript συνήθως θα σταματήσει και θα δημιουργήσει ένα μήνυμα σφάλματος.
Το τεχνικό όρο για αυτό είναι: Η JavaScript θα “ρίξει” μια εξαίρεση (θα προκαλέσει ένα σφάλμα).
Η δήλωση throw
σας επιτρέπει να δημιουργήσετε ένα προσαρμοσμένο σφάλμα.
Τεχνικά, μπορείτε να “ρίξετε” μια εξαίρεση (να προκαλέσετε ένα σφάλμα).
Η εξαίρεση μπορεί να είναι ένα αλφαριθμητικό JavaScript, ένας αριθμός, ένα boolean ή ένα αντικείμενο. Η δήλωση throw
συνήθως χρησιμοποιείται για να υποδείξει ότι κάτι πήγε λάθος στον κώδικα, και μπορεί να είναι χρήσιμη για τη διαχείριση σφαλμάτων και την παροχή σαφών μηνυμάτων σφάλματος στους προγραμματιστές ή τους χρήστες.
Παράδειγμα χρήσης:
function divide(a, b) { if (b === 0) { throw "Division by zero is not allowed!"; } return a / b; } try { console.log(divide(10, 2)); console.log(divide(8, 0)); // This will throw an error } catch (error) { console.error("An error occurred:", error); }
Το παρακάτω παράδειγμα εξετάζει μια είσοδο. Εάν η τιμή είναι εσφαλμένη, προκαλείται μια εξαίρεση (err).
Η εξαίρεση (err) πιάνεται από τη δήλωση catch και εμφανίζεται ένα προσαρμοσμένο μήνυμα σφάλματος:
function validateInput(input) { if (typeof input !== "number") { throw "Input must be a number!"; } if (input < 0) { throw "Input must be a positive number!"; } return input; } try { let userInput = parseInt(prompt("Enter a positive number:")); let validInput = validateInput(userInput); console.log("Valid input:", validInput); } catch (error) { console.error("Error:", error); }
Σε αυτό το παράδειγμα, ο χρήστης καλείται να εισάγει ένα θετικό αριθμό. Εάν η είσοδος δεν είναι ένας αριθμός ή είναι αρνητική, προκαλείται μια εξαίρεση με ένα προσαρμοσμένο μήνυμα σφάλματος. Η εξαίρεση πιάνεται στη δήλωση catch
και εμφανίζεται ένα μήνυμα σφάλματος στην κονσόλα.
Η JavaScript διαθέτει ένα ενσωματωμένο αντικείμενο σφάλματος που παρέχει πληροφορίες σχετικά με το σφάλμα που προκλήθηκε.
Το αντικείμενο σφάλματος παρέχει δύο χρήσιμες ιδιότητες: το όνομα (name
) και το μήνυμα (message
).
Παράδειγμα:
try { // Προκαλούμε ένα σφάλμα throw new Error("This is a custom error message."); } catch (error) { console.error("Error name:", error.name); console.error("Error message:", error.message); }
Σε αυτό το παράδειγμα, προκαλούμε ένα προσαρμοσμένο σφάλμα χρησιμοποιώντας την κατασκευή new Error()
. Στη συνέχεια, εκτυπώνουμε το όνομα και το μήνυμα του σφάλματος.
[adinserter block=”3″]
Η ιδιότητα name
του αντικειμένου σφάλματος μπορεί να επιστρέψει έξι διαφορετικές τιμές, ανάλογα με τον τύπο του σφάλματος:
Error
: Καθολικό όνομα για σφάλματα που δεν έχουν άλλο προσδιορισμένο όνομα.SyntaxError
: Σφάλμα κατά την ανάλυση (parsing) του κώδικα.TypeError
: Σφάλμα λόγω ανεπαρκούς τύπου δεδομένων.ReferenceError
: Σφάλμα όταν μια μη υπαρκτή μεταβλητή αναφέρεται.RangeError
: Σφάλμα όταν μια τιμή βρίσκεται εκτός εύρους που είναι επιτρεπτό.URIError
: Σφάλμα κατά την ανακωδικοποίηση μιας URI.
Παράδειγμα:
try { // Προκαλούμε ένα TypeError null(); // Αυτό δεν είναι έγκυρη κλήση συνάρτησης } catch (error) { console.error("Error name:", error.name); // Θα εμφανίσει "TypeError" console.error("Error message:", error.message); }
Στο παραπάνω παράδειγμα, προκαλούμε ένα TypeError
επειδή καλούμε τη μεταβλητή null
ως συνάρτηση. Το όνομα του σφάλματος που παράγεται είναι "TypeError"
.
Το EvalError
υποδεικνύει ένα σφάλμα στη λειτουργία eval()
.
Το eval()
είναι μια ενσωματωμένη συνάρτηση της JavaScript που χρησιμοποιείται για τη δυναμική αξιολόγηση κώδικα από μια συμβολοσειρά. Το EvalError
είναι μια υποκλάση της Error
που χρησιμοποιείται ειδικά για να υποδεικνύει σφάλματα που συμβαίνουν κατά την εκτέλεση της eval()
.
Παράδειγμα:
try { eval("alert('Hello, world!')"); } catch (error) { if (error instanceof EvalError) { console.error("EvalError:", error.message); } else { console.error("Other error:", error.message); } }
Στο παραπάνω παράδειγμα, χρησιμοποιούμε τη συνάρτηση eval()
για να εκτελέσουμε κώδικα. Εάν συμβεί ένα σφάλμα κατά την εκτέλεση της eval()
, η catch
δήλωση θα ελέγξει εάν το σφάλμα είναι μια EvalError
και θα εμφανίσει το αντίστοιχο μήνυμα.
Το RangeError
προκαλείται όταν χρησιμοποιείτε έναν αριθμό που βρίσκεται εκτός του εύρους των νόμιμων τιμών.
Παράδειγμα:
try { let arr = [1, 2, 3]; console.log(arr[5]); // Προσπαθούμε να αποκτήσουμε πρόσβαση σε μια μη υπαρκτή θέση του πίνακα } catch (error) { if (error instanceof RangeError) { console.error("RangeError:", error.message); } else { console.error("Other error:", error.message); } }
Στο παραπάνω παράδειγμα, προσπαθούμε να αποκτήσουμε πρόσβαση στο στοιχείο με τη θέση 5 ενός πίνακα που έχει μόνο 3 στοιχεία. Επειδή αυτό βρίσκεται εκτός του εύρους των νόμιμων τιμών, προκαλείται ένα RangeError
. Η δήλωση catch
ελέγχει εάν το σφάλμα είναι ένα RangeError
και εμφανίζει το αντίστοιχο μήνυμα.
Το ReferenceError
προκαλείται όταν χρησιμοποιείτε (αναφορά σε) μια μεταβλητή που δεν έχει δηλωθεί.
Παράδειγμα:
try { console.log(x); // Προσπαθούμε να αναφερθούμε στη μεταβλητή x που δεν έχει δηλωθεί } catch (error) { if (error instanceof ReferenceError) { console.error("ReferenceError:", error.message); } else { console.error("Other error:", error.message); } }
Στο παραπάνω παράδειγμα, προσπαθούμε να αναφερθούμε στη μεταβλητή x
που δεν έχει δηλωθεί. Επειδή αυτή η μεταβλητή δεν υπάρχει, προκαλείται ένα ReferenceError
. Η δήλωση catch
ελέγχει εάν το σφάλμα είναι ένα ReferenceError
και εμφανίζει το αντίστοιχο μήνυμα.
Το SyntaxError
προκαλείται όταν προσπαθείτε να αξιολογήσετε κώδικα με συντακτικό σφάλμα.
Παράδειγμα:
try { eval("console.log('Hello, world!'"); // Λείπει το κλείσιμο της παρένθεσης } catch (error) { if (error instanceof SyntaxError) { console.error("SyntaxError:", error.message); } else { console.error("Other error:", error.message); } }
Στο παραπάνω παράδειγμα, προσπαθούμε να εκτελέσουμε κώδικα με συντακτικό σφάλμα, καθώς λείπει το κλείσιμο της παρένθεσης στη συνάρτηση console.log()
. Επειδή αυτό προκαλεί ένα συντακτικό σφάλμα, προκαλείται ένα SyntaxError
. Η δήλωση catch
ελέγχει εάν το σφάλμα είναι ένα SyntaxError
και εμφανίζει το αντίστοιχο μήνυμα.
[adinserter block=”4″]
Το TypeError
προκαλείται όταν χρησιμοποιείτε μια τιμή που βρίσκεται εκτός του εύρους των αναμενόμενων τύπων.
Παράδειγμα:
try { let x = null; x.toUpperCase(); // Η μέθοδος toUpperCase() δεν μπορεί να κληθεί σε null τύπο } catch (error) { if (error instanceof TypeError) { console.error("TypeError:", error.message); } else { console.error("Other error:", error.message); } }
Στο παραπάνω παράδειγμα, προσπαθούμε να καλέσουμε τη μέθοδο toUpperCase()
σε μια μεταβλητή τύπου null
. Επειδή αυτό δεν είναι εφικτό, προκαλείται ένα TypeError
. Η δήλωση catch
ελέγχει εάν το σφάλμα είναι ένα TypeError
και εμφανίζει το αντίστοιχο μήνυμα.
Το URIError
προκαλείται όταν χρησιμοποιείτε μη έγκυρους χαρακτήρες σε μια συνάρτηση URI.
Παράδειγμα:
try { decodeURIComponent("%"); // Ο χαρακτήρας "%" δεν είναι έγκυρος σε URI } catch (error) { if (error instanceof URIError) { console.error("URIError:", error.message); } else { console.error("Other error:", error.message); } }
Στο παραπάνω παράδειγμα, προσπαθούμε να ανακωδικοποιήσουμε τον χαρακτήρα “%” που δεν είναι έγκυρος σε μια συνάρτηση URI. Επειδή αυτό προκαλεί μια URI που δεν είναι έγκυρη, προκαλείται ένα URIError
. Η δήλωση catch
ελέγχει εάν το σφάλμα είναι ένα URIError
και εμφανίζει το αντίστοιχο μήνυμα.