In stored procedures kunnen fouten worden afgehandeld met speciale constructies.
In SQL Server zijn de belangrijkste mechanismen de TRY...CATCH-blokken, waarin alle fouten binnen TRY worden opgevangen, en in CATCH kunnen de details worden vastgelegd. Er zijn functies zoals ERROR_NUMBER(), ERROR_MESSAGE() beschikbaar voor het verkrijgen van details.
BEGIN TRY -- Risicovolle operatie UPDATE Accounts SET balance = balance - 100 WHERE id = 1; END TRY BEGIN CATCH INSERT INTO ErrorLog( ErrorTime, ErrorNumber, ErrorMessage, UserName ) VALUES ( GETDATE(), ERROR_NUMBER(), ERROR_MESSAGE(), SUSER_SNAME() ); -- Extra herstel of ROLLBACK END CATCH
In Oracle worden vaak EXCEPTION-blokken gebruikt:
BEGIN UPDATE ...; EXCEPTION WHEN OTHERS THEN INSERT INTO error_log VALUES (..., SQLERRM); END;
Punten om te onthouden:
Kan een uitzondering in het CATCH-blok leiden tot verlies van de foutcontext? Hoe implementeer je geneste foutafhandeling?
Antwoord en voorbeeld: Als er een fout optreedt in het CATCH-blok (bijvoorbeeld door de onbeschikbaarheid van de tabel ErrorLog), gaat de oorspronkelijke foutcontext verloren en kan informatie over de oorzaak van de storing verloren gaan.
Om jezelf te beschermen, encapsuleer het loggen in een aparte procedure met een eigen TRY...CATCH, zodat je altijd "fout in de foutafhandelaar" kunt vangen.
BEGIN TRY -- hoofdcode END TRY BEGIN CATCH EXEC LogError @Error = ERROR_MESSAGE(); END CATCH -- De LogError-procedure bevat zelf zijn eigen TRY...CATCH
Verhaal
Project: Financiële rapportage. In de stored procedures hebben we TRY...CATCH-blokken toegevoegd, maar we hebben de parameters die de fout veroorzaakten niet gelogd. Dit leidde tot het handmatig zoeken naar situaties uit de backup bij het vangen van kritieke storingen - de root cause was niet duidelijk.
Verhaal
Project: Automatisering van documentstromen (Oracle). In het EXCEPTION-blok vergaten we de gebruikersnaam te loggen. Na een week onderzoek ontdekten we dat iemand opzettelijk documenten "wijzigde" - dit hebben we alleen kunnen vaststellen aan de hand van indirecte aanwijzingen in het auditlog.
Verhaal
Project: E-commerce. De procedure logde een fout in ErrorLog bij een storing. Op een dag was de Log-tabel geblokkeerd door een groeiende transactie, en de poging tot loggen leidde tot een geneste fout, die de originele oorzaak overschreef en de foutstack schoonmaakte. Dit hebben we opgelost door een extra tabel voor kritieke storingen en meervoudig loggen te implementeren.