ASPNL logo (1 kb)
Saturday, February 04, 2012




Microsoft MVP

.NET Codewise Community
<< vorige | overzicht | volgende >>

Fouten afhandelen en opsporing in ASP.NET

Door Michiel van Otegem
28 juli 2006

Een applicatie waarin fouten niet goed afgehandeld worden is in eerste instantie vervelend voor de gebruikers. Daarnaast kan het nare gevolgen hebben voor de server. Het is dus zaak om fouten netjes af te handelen en om de middelen te hebben fouten zonodig op te sporen. Hierin kunnen zowel de ontwikkelaar als de systeembeheerder een rol spelen. De mogelijkheden die ontwikkelaars hebben om de systeembeheerder te helpen komen in het volgende artikel aan bod.

ASP.NET en het .NET Framework zijn op zich zelf een stuk stabieler dan ASP en applicaties die direct met Windows communiceren, zoals bijvoorbeeld applicaties geschreven in Visual Basic 6.0. Het .NET Framework biedt een runtime omgeving die het geheugen voor applicaties beheert en zorgt dat applicaties niet in elkaars vaarwater terecht komen. Het voordeel van geheugenbeheer is dat fouten in de programmatuur niet zomaar voor geheugenlekken kunnen zorgen, omdat er sprake is van garbage collection op het geheugen. Geheugen dat niet meer nodig is wordt door de garbage collector vrijgegeven. In bijvoorbeeld ASP en Visual Basic 6 is dat niet zo, dus moet de ontwikkelaar zorgvuldig het gebruikte geheugen vrijgeven, ook als er fouten optreden. Dat het .NET Framework veel van deze taken op zich neemt, betekent overigens niet dat de ontwikkelaar zich nergens meer zorgen over hoeft te maken. Zo is het bijvoorbeeld nog steeds heel belangrijk dat database verbindingen correct worden afgesloten.
Naast de verbeteringen die de runtime omgeving biedt, zijn in ASP.NET ook de mogelijkheden om fouten op te sporen en af te handelen veel beter. Foutafhandeling is in ASP.NET structureel aangepakt, en als zodanig een belangrijk en goed instelbaar onderdeel. De makkelijkste manier van foutafhandeling is een gebruiker doorverwijzen naar een andere pagina. Er gebeurt dan weliswaar niet wat de gebruiker wil, maar hij/zij krijgt in ieder geval geen onbegrijpelijke onzin op het scherm. In Internet Information Server (IIS) heb je de mogelijkheid om een gebruiker door te verwijzen ook al, maar in ASP.NET is dit handiger geïmplementeerd. Je kunt de afhandelingspagina's instellen via het configuratiebestand web.config dat ik in eerdere artikelen al uitgebreid heb besproken. De afdeling system.web in web.config bevat het element customErrors voor de configuratie van de foutafhandeling. Het mode attribuut van het customErrors element bepaalt wanneer een gebruiker wel of niet een nette foutpagina te zien krijgt, en kan drie instellingen hebben: Off, On, of RemoteOnly. In het eerste geval krijgen gebruikers gewoon de foutmelding te zien, in het tweede geval krijgen alle gebruikers een nette foutpagina te zien, en in het derde geval krijgen gebruikers van buitenaf een nette foutpagina te zien, maar krijgen bezoekers van localhost (dus van de lokale computer) de foutmelding te zien. Dit is in principe de beste instelling, omdat normale gebruikers dan nooit de fout te zien krijgen, maar de beheerder wel (iets wat in IIS niet mogelijk is). Het tweede attribuut van het customErrors element, defaultRedirect, bepaalt welke pagina een bezoeker te zien krijgt als er een fout optreedt. Als dit attribuut geen waarde heeft verzorgt ASP.NET zelf een nette foutmelding (zonder verwijzing naar de daadwerkelijke fout in de code). Het customErrors element kan één of meerdere error elementen bevatten, die per soort fout een andere pagina kan laten zien. Welke fout een error element afhandelt, wordt bepaald door de waarde van het statusCode attribuut. Dit attribuut moet een geldige HTTP status code bevatten. Het redirect attribuut geeft vervolgens aan welke pagina moet worden weergegeven. Figuur 1 laat een web.config bestand zien dat instellingen bevat voor foutafhandeling door pagina's waarnaar wordt doorverwezen.

<configuration>
 <system.web>
  <customErrors
     mode="RemoteOnly"
     defaultRedirect="error.aspx">
   <error
     statusCode="404"
     redirect="notfound.htm"/>
   <error
     statusCode="500"
     redirect="error500.aspx"/>
  </customErrors>
 </system.web>
</configuration>
Figuur 1, web.config met instellingen voor foutafhandeling

In Figuur 1 wordt de pagina error500.aspx weergegeven als er een fout optreedt bij het uitvoeren van een ASP.NET pagina. Dat dit zelf een ASP.NET pagina is, betekent dat je bijvoorbeeld met de foutpagina de fout kan opslaan in een log (hierover later meer). Als de gebruiker een pagina opvraagt die niet bestaat, dan wordt notfound.htm weergegeven. Bij alle andere soorten fouten wordt de gebruiker doorverwezen naar error.aspx. Al deze instellingen gelden niet voor gebruikers die via localhost pagina's opvragen. Die krijgen wel eventuele foutmeldingen te zien.
Het handige van web.config is dat je in een submap van de applicatie een web.config kan zetten die bepaalde instellingen overschrijft voor die map (en de onderliggende mappen). Zo kun je dus voor verschillende mappen van de applicatie naar verschillende pagina's verwijzen voor het afhandelen van fouten, en kun je voor bepaalde mappen zelfs de foutafhandeling uit zetten door mode="Off" te gebruiken. Dit is handig als iemand van buiten de server komt, maar toch moet kunnen zien wat er fout gaat. Voor die persoon kun je een beveiligde map maken, waarvoor foutafhandeling uit staat. Wil je nog meer controle over welke pagina iemand te zien krijgt als er een fout optreedt bij het compileren of uitvoeren van een pagina, dan kun je ook per pagina nog opgeven naar welke pagina de gebruiker moet worden doorverwezen. Dit kun je doen met behulp van de ErrorPage eigenschap van de Page directive, als volgt:

< %@ Page ErrorPage="error500-1.aspx" %>

Door de bovenstaande directive te gebruiken, wordt de gebruiker doorverwezen naar error500-1.aspx, zelfs als web.config uit figuur 1 actief is.

Debug informatie

Wanneer foutafhandeling uit staat, overal dan wel lokaal, hangt nog van andere instellingen af wat je te zien krijgt. Zijn er geen andere instellingen gedaan en treedt een fout op in een pagina, dan krijg je zoiets te zien als in figuur 2.


Figuur 2, Standaardfoutpagina als debugging uit staat

Figuur 2 geeft alleen de foutmelding weer. Overige informatie die je kan helpen bij het oplossen van de fout (met name de broncode) wordt niet weergegeven vanuit veiligheidsoverwegingen. Als je meer wil zien dan in figuur 2, dien je voor de pagina of voor de applicatie debugging aan te zetten. Voor een pagina kun je dit aangeven in de pagina declaratie, als volgt:

<%@ Page Language="VB" Debug="true" %>

Omdat het erg onhandig is om dit voor alle pagina's aan of uit te moeten zetten, kun je dit ook instellen in web.config, zoals in figuur 3. De instelling van figuur 3 wordt gebruikt als er geen instelling in de pagina staat. Je kunt dus per pagina bepalen of je de standaardinstelling gebruikt of niet. Als debugging aan staat, krijg je in plaats van figuur 2 zoiets te zien als in figuur 4 (sterker nog, dit is dezelfde pagina als van figuur 2, maar dan met debugging aan).

<configuration>
 <system.web>
  <compilation debug="true"/>
 </system.web>
</configuration>
Figuur 3, web.config met debugging standaard aan


Figuur 4, Pagina waarvoor debugging aan staat

De instellingen voor debugging hebben alleen betrekking op fouten die optreden tijdens het uitvoeren van een pagina. Als er een fout optreedt bij het compileren van de pagina, dan wordt de broncode wel getoond, zoals je kunt zien in figuur 5. Aangezien het vanuit een beveiligingsoogpunt onverstandig is om broncode mee te sturen, is het dus belangrijk dat dit normaal gezien alleen voor lokale gebruikers het geval is.


Figuur 5, Compiler fouten worden wel weergegeven

Fouten en problemen opsporen

Een foutmelding hoeft op zich zelf niet altijd genoeg informatie te geven om de fout op te lossen. Dit geldt helemaal voor zaken die niet echt fout zijn, maar die een bottleneck vormen bij het serveren van een pagina. Wil je dergelijke problemen kunnen opsporen, dan moet je kunnen zien wat er gebeurt en in welk volgorde. In ASP kon je dit alleen doen door zelf een soort trace log te maken, door op strategische punten tekst naar de browser te schrijven. In ASP.NET is hier een voorziening voor, die je allerhande informatie geeft over het uitvoeren van de pagina. Hierbij wordt niet alleen informatie getoond over de volgorde waarin de code wordt uitgevoerd, maar ook informatie die van belang is voor het uitvoeren van de pagina, zoals informatie over het HTTP request waarmee de pagina is opgevraagd. Verder kan de ontwikkelaar ook informatie schrijven naar de trace log. In figuur 6 zie je een gedeelte van de trace informatie die met een pagina wordt meegestuurd.


Figuur 6, Trace informatie van een pagina

Net als debugging kun je tracing zowel in de pagina als in web.config aan of uit zetten. In een pagina doe je dat als volgt:

<%@ Page Language="VB" Trace="true" %>

Deze instelling overschrijft de instelling die in web.config staat. In web.config kun je echter nog meer instellingen doen. De belangrijkste instellingen kun je zien in figuur 7.

<configuration>
 <system.web>
  <trace
     enabled="true"
     pageOutput="false"
     requestLimit="15"
     localOnly="true"/>
 </system.web>
</configuration>
Figuur 7, web.config met trace instellingen

In figuur 7 worden de instellingen voor tracing gedaan via het trace element. Met het enabled attribuut wordt aangegeven of tracing aan of uit staat. Met het pageOutput attribuut kun je bepalen of de trace informatie in de pagina getoond moet worden of niet. Dit lijkt een beetje vreemd, omdat het weinig nut lijkt te hebben om tracing aan te hebben staan, terwijl het niet in de pagina getoond wordt. De trace informatie wordt echter ook tijdelijk opgeslagen en is dus later te bekijken. Het aantal requests dat opgeslagen wordt, kun je aangeven met het requestLimit attribuut. De opgeslagen trace informatie kun je oproepen via trace.axd in de hoofdmap van de applicatie, dus bijvoorbeeld via http://www.voorbeeld.nl/trace.axd. Je krijgt dan zoiets te zien als in figuur 8. Of je trace.axd van buitenaf kunt opvragen, kun je instellen via het localOnly attribuut. Alleen als dit expliciet op false gezet is, kun je trace.axd vanaf een andere computer opvragen.


Figuur 8, Trace log

In figuur 8 zie je alle opgeslagen requests. Door op "view details" van een van de requests te klikken krijg je de trace informatie te zien zoals in figuur 6.

Conclusie

Foutafhandeling en –opsporing is in ASP.NET structureel en zeer verfijnd opgezet. Systeembeheerders kunnen hierdoor makkelijk de foutafhandeling structureel opzetten. Daar waar nodig kan de systeembeheerder of de ontwikkelaar de instellingen overschrijven voor een gedeelte van de applicatie of zelfs één pagina. Het volgende artikel zal laten zien hoe je de bestaande structuur kunt uitbreiden, ten eerste door als ontwikkelaar trace informatie naar de trace log te schrijven, ten tweede door gebruik te maken van de Windows Event Log.

Dit artikel is eerder verschenen in Windows & .NET Magazine Benelux, oktober 2002 (huidige naam NetOpus)

<< vorige | ^ naar boven | overzicht | volgende >>
copyright 2000-2007 ASPNL