Async await hibák kezelése API hívásokban

Async/Await hibakezelés JavaScriptben: ne essünk csapdába API hívásoknál

Üdv a kódfronton! Ha már JavaScript-et írsz, valószínűleg találkoztál az async/await szintaxissal, ami átalakította, ahogy aszinkron műveletekkel dolgozunk. De amikor API hívásokról van szó, a hibakezelés gyakran a fejlesztők buktatója lesz. Ma részletezem, milyen mintákat érdemes követni, hogy kódunk ne dőljön össze, amikor a backend néha „nem érez jól”.

Miért fontos a szilárd hibakezelés?

Amikor fetch() vagy axios segítségével hívunk meg egy API-t, számos dolog mehet félre: hálózati probléma, 500-os szerverhiba, érvénytelen JSON válasz, vagy épp a felhasználó gyors megnyomja a frissítést. Az async/await szépen leegyszerűsíti az aszinkron kódot, de ha nem kezeljük explicit a hibákat, a felhasználó csupán egy „fekete lyukat” fog látni.

Az alapok: try-catch blokk

A legelterjedtebb minta a try...catch használata async függvényen belül:

async function fetchUserData(userId) {
    try {
        const response = await fetch(`/api/users/${userId}`);
        
        if (!response.ok) {
            throw new Error(`HTTP hiba! Státusz: ${response.status}`);
        }
        
        const data = await response.json();
        return data;
    } catch (error) {
        console.error('API hívás sikertelen:', error.message);
        // Felhasználóbarát üzenet megjelenítése
        showNotification('Az adatok betöltése sikertelen. Kérjük, próbáld újra.');
        return null;
    }
}

A kulcsfontosságú rész itt az if (!response.ok) ellenőrzés. A fetch() csak hálózati hibákra dob kivételt, de a 404-es vagy 500-as státuszkódokat nem! Ezeket nekünk kell explicit kezelnünk.

Gyakori buktatók, amiket érdemes elkerülni

1. Elfelejtjük a response.ok ellenőrzést – Ez a legnagyobb hiba. A fetch sikeresnek tekint egy 404-es választ is, mert technikailag „kapottunk választ”.

2. Túl általános catch blokk – Ne csak logoljunk, hanem típusonként különböző kezelést alkalmazzunk.

3. Nincs timeout kezelés – Az API hívások néha „lelógnak”. Érdemes timeout-ot beállítani:

async function fetchWithTimeout(url, timeout = 8000) {
    const controller = new AbortController();
    const timeoutId = setTimeout(() => controller.abort(), timeout);
    
    try {
        const response = await fetch(url, { signal: controller.signal });
        clearTimeout(timeoutId);
        
        if (!response.ok) throw new Error(`HTTP ${response.status}`);
        return await response.json();
    } catch (error) {
        clearTimeout(timeoutId);
        if (error.name === 'AbortError') {
            throw new Error('A kérés túllépte az időkeretet');
        }
        throw error;
    }
}

Integráció PHP backenddel és jQuery frontenddel

Nézzünk egy teljesebb példát, ahol PHP backenddel és jQuery/Bootstrap frontenddel dolgozunk:

Backend (PHP):

query('SELECT id, name, price FROM products WHERE active = 1');
    $products = $stmt->fetchAll(PDO::FETCH_ASSOC);
    
    http_response_code(200);
    echo json_encode(['success' => true, 'data' => $products]);
} catch (Exception $e) {
    http_response_code(500);
    echo json_encode(['success' => false, 'error' => 'Szerverhiba történt']);
}
?>

Frontend (jQuery + Bootstrap + JavaScript):

async function loadProducts() {
    // Bootstrap loading state
    $('#product-list').html(`
        <div class="text-center my-4">
            <div class="spinner-border text-primary" role="status">
                <span class="visually-hidden">Betöltés...</span>
            </div>
        </div>
    `);
    
    try {
        const response = await $.ajax({
            url: '/api/get_products.php',
            method: 'GET',
            dataType: 'json',
            timeout: 10000
        });
        
        if (!response.success) {
            throw new Error(response.error || 'Ismeretlen hiba');
        }
        
        renderProducts(response.data);
    } catch (error) {
        let errorMessage = 'A termékek betöltése sikertelen.';
        
        if (error.status === 404) {
            errorMessage = 'Az API végpont nem található.';
        } else if (error.status === 500) {
            errorMessage = 'Szerverhiba. Kérjük, próbáld később.';
        } else if (error.statusText === 'timeout') {
            errorMessage = 'A kérés túl sokáig tart. Ellenőrizd az internetkapcsolatot.';
        }
        
        // Bootstrap alert megjelenítése
        $('#product-list').html(`
            <div class="alert alert-danger alert-dismissible fade show" role="alert">
                ${errorMessage}
                <button type="button" class="btn-close" data-bs-dismiss="alert"></button>
            </div>
        `);
    }
}

function renderProducts(products) {
    // SCSS/CSS stílusozott megjelenítés
    const html = products.map(product => `
        <div class="product-card card shadow-sm mb-3">
            <div class="card-body">
                <h5 class="card-title">${product.name}</h5>
                <p class="card-text text-primary fw-bold">${product.price} Ft</p>
            </div>
        </div>
    `).join('');
    
    $('#product-list').html(html);
}

// Oldal betöltésekor
$(document).ready(function() {
    loadProducts();
    
    // Frissítés gomb
    $('#refresh-btn').on('click', loadProducts);
});

Haladó minta: újrapróbálkozás (retry logic)

Néha érdemes adott hibák esetén újrapróbálkozni, pl. hálózati időtúllépésnél:

async function fetchWithRetry(url, maxRetries = 3) {
    let lastError;
    
    for (let i = 0; i  setTimeout(resolve, 1000));
                continue;
            }
            break;
        }
    }
    
    throw lastError;
}

Összegzés

Az async/await hibakezelése API hívásoknál nem csak technikai kérdés, hanem felhasználói élménybeli is. A legfontosabb tanácsok:

1. Mindig kezeld a HTTP státuszkódokat (response.ok) 2. Használj specifikus hibakezelést a különböző hibafajtákra 3. Jelzés a felhasználónak – Bootstrap alert, spinner, vagy más visszajelzés 4. Időtúllépés kezelése kötelező 5. Érdemes logolni a hibákat (fejlesztéshez), de a felhasználónak emberbarát üzenetet mutatni

Ne feledd: a jó hibakezelés nem csak a kód stabilitását növeli, hanem azt is jelzi a felhasználóknak, hogy alkalmazásod professzionális és megbízható. Legközelebb, amikor API-t hívsz, kérdezd meg magadtól: „Mi történik, ha minden szétesik?” – és írd meg a választ kódban.

Boldog hibakezelést!