Fout afhandeling

T. Issaris

26 April 2021

Fout afhandeling

Defensief programmeren: “verdedigen” tegen mogelijk foutieve invoer

Zonder foutafhandeling

def bmi(gewicht, lengte):
    return gewicht / lengte**2

b = bmi(77, 1.87)
print(f"BMI: {b}")

Wat bij ongeldige parameter?

def bmi(gewicht, lengte):
    return gewicht / lengte**2

b = bmi(77, 0) # ?
Traceback (most recent call last):
  File "prog2/eh001.py", line 4, in <module>
    b = bmi(77, 0) # ?
  File "prog2/eh001.py", line 2, in bmi
    return gewicht / lengte**2
ZeroDivisionError: integer division or modulo by zero

Programmeertaal C

De programmeertaal C wordt nog steeds veel gebruikt voor onder andere systeembibliotheken omwille van de hoge performatie en algemene beschikbaarheid.

Programmeertaal C: foutafhandeling

Om aan te geven dat een operatie niet uitgevoerd kan worden, wordt dikwijls gebruik gemaakt van een “speciale” waarde.

Voorbeeld: BMI berekenen in C

#include <stdio.h>

float bmi(float gewicht, float lengte) {
    return gewicht / (lengte * lengte);
}

int main() {
    float b = bmi(80, 1.835);
    printf("BMI: %f", b);
}

Wat als gewicht negatief is?

Gebruik speciale waarde -1

#include <stdio.h>

float bmi(float gewicht, float lengte) {
    if (gewicht <= 0) return -1;
    if (lengte <= 0) return -1;
    return gewicht / (lengte * lengte);
}

int main() {
    float b = bmi(-1, 1.835);
    if (b == -1) {
        printf("error!");
    } else {
        printf("BMI: %f", b);
    }
}

Special return value: -1

def bmi(gewicht, lengte):
    if gewicht <= 0:
        return -1
    if lengte <= 0:
        return -1
    return gewicht / lengte**2

b = bmi(77, 1.87)
if b == -1:
    print("error!")
else:
    print(f"BMI: {b}")

Special return value: None

def bmi(gewicht, lengte):
    if gewicht <= 0:
        return None
    if lengte <= 0:
        return None
    return gewicht / lengte**2

b = bmi(77, 1.87)
if b is None:
    print("error!")
else:
    print(f"BMI: {b}")

Raising exceptions

def bmi(gewicht, lengte):
    if gewicht <= 0:
        raise RuntimeError("gewicht fout")
    if lengte <= 0:
        raise RuntimeError("lengte fout")
    return gewicht / lengte**2

b = bmi(0, 1.87)
print(f"BMI: {b}")

Exception handling

def bmi(gewicht, lengte):
    if gewicht <= 0:
        raise RuntimeError("gewicht fout")
    if lengte <= 0:
        raise RuntimeError("lengte fout")
    return gewicht / lengte**2

try:
    b = bmi(0, 1.87)
    print(f"BMI: {b}")
except RuntimeError:
    print("error")

Custom exceptions

class GewichtError(RuntimeError):
    pass

class LengteError(RuntimeError):
    pass

def bmi(gewicht, lengte):
    if gewicht <= 0:
        raise GewichtError
    if lengte <= 0:
        raise LengteError
    return gewicht / lengte ** 2


try:
    b = bmi(0, 1.87)
    print(f"BMI: {b}")
except GewichtError:
    print("probleem met gewicht")
except LengteError:
    print("probleem met lengte")

SQL

Toon alle namen en emailadressen van studenten:

SELECT name, email FROM student

SQL

Toon het emailadres van student met naam Jan Peeters:

SELECT email FROM student WHERE name == 'Jan Peeters'

SQL

Vernietig tabel student:

DROP TABLE student

SQL

query = "SELECT name, email FROM student"
execute(query)

SQL

query = "SELECT email FROM student WHERE name = 'Jan Peeters'"
execute(query)

SQL

query = input("Voer een SQL SELECT query in:")
# gebruiker typt: SELECT name, email FROM student
execute(query)

SQL

query = input("Voer een SQL SELECT query in:")
# gebruiker typt: DROP TABLE student
execute(query) # 😱

SQL

naam = input("Geef de naam van de student:")
# gebruiker typt: Jan Peeters
query = f"SELECT email FROM student WHERE name = '{naam}'"
execute(query)

SQL injection attack

execute = print
naam = input("Geef de naam van de student:")
# gebruiker typt: Jan Peeters'; DROP TABLE student; --
query = f"SELECT email FROM student WHERE name = '{naam}'"
execute(query) # 😱

SQL injection attack

Little Bobby Tables

Oplossing: prepared statements

naam = input("Geef de naam van de student:")
# gebruiker typt: Jan Peeters
execute("SELECT email FROM student WHERE name = %s", naam)
# OK

Oplossing: prepared statements

naam = input("Geef de naam van de student:")
# gebruiker typt: Jan Peeters'; DROP TABLE student; --
execute("SELECT email FROM student WHERE name = %s", naam)
# error melding 😎
// reveal.js plugins