Exemple complet pour les gestionnaires d'erreurs

Mise à jour : novembre 2007

Cet exemple de code inclut des éléments pour la gestion des exceptions à la fois au niveau de la page et au niveau de l'application.

Fichiers d'exemple de code

Les fichiers de cet exemple de code sont les suivants :

  • Web.config

  • Global.asax

  • Default.aspx

  • ExceptionUtility (à placer dans le dossier App_Code)

  • GenericErrorPage.aspx

  • HttpErrorPage.aspx

Web.config

L'exemple suivant fournit le fichier Web.config. Le paramètre initial de customErrors redirigera toutes les erreurs non gérées vers le fichier HttpErrorPage.aspx.

<configuration>
  <appSettings/>
  <connectionStrings/>
  <system.web>
    <compilation debug="true" />

    <!-- Turn on Custom Errors -->
    <customErrors 
      mode="RemoteOnly"
      defaultRedirect="HttpErrorPage.aspx">
    </customErrors >

  </system.web>
</configuration>

Global.asax

L'exemple suivant fournit le fichier Global.asax. Pour activer le gestionnaire d'événements d'erreur dans le fichier Global.asax, vous devrez modifier le fichier Web.config. Le fichier de configuration est prioritaire. Par conséquent, vous devez affecter à customErrors la valeur Off ou supprimer le paramètre defaultRedirect. Si l'élément customErrors de votre fichier de configuration Web.config a la valeur Off, le gestionnaire d'événements Application_Error dans Global.asax traitera toutes les erreurs non gérées.

Note de sécurité :

N'affectez jamais à customErrors la valeur Off dans votre fichier Web.config si vous n'avez pas de gestionnaire Application_Error dans votre fichier Global.asax. Des informations potentiellement compromettantes sur votre site Web peuvent être exposées à n'importe quelle personne susceptible de provoquer une erreur sur votre site.

void Application_Error(object sender, EventArgs e) 
{ 
    // Code that runs when an unhandled error occurs
    // Give the user some information, but
    // stay on the default page
    Exception exc = Server.GetLastError();
    Response.Write("<h2>Global Page Error</h2>\n");
    Response.Write(
        "<p>" + exc.Message + "</p>\n");
    Response.Write("Return to the <a href='Default.aspx'>" +
        "Default Page</a>\n");

    // Log the exception and notify system operators
    ExceptionUtility.LogException(exc, "DefaultPage");
    ExceptionUtility.NotifySystemOps(exc);

    // Clear the error from the server
    Server.ClearError();
}

ExceptionUtility

L'exemple suivant fournit le fichier ExceptionUtility. Les journaux d'erreurs peuvent être dirigés vers le fichier ErrorLog de l'ordinateur ou, si l'ordinateur fait partie d'une batterie de serveurs Web, le journal d'erreurs peut être enregistré dans un fichier texte globalement disponible, ou même une base de données. Vous devrez peut-être également informer immédiatement les administrateurs système qu'un problème est survenu. L'élément ExceptionUtility suivant a deux méthodes statiques : une pour enregistrer l'exception et une pour informer les administrateurs système. La façon dont ces méthodes sont implémentées dans votre code dépend des besoins de votre organisation. Pour cet exemple, vous devez accorder des autorisations en écriture au SERVICE RÉSEAU pour le dossier App_Data afin de permettre à l'application d'écrire dans le journal d'erreurs.

using System;
using System.IO;
using System.Web;

// Create our own utility for exceptions
public sealed class ExceptionUtility
{
    // All methods are static, so this can be private
    private ExceptionUtility()
    { }

    // Log an Exception
    public static void LogException(Exception exc, string source)
    {
        // Include enterprise logic for logging exceptions
        // Get the absolute path to the log file
        string logFile = "App_Data/ErrorLog.txt";
        logFile = HttpContext.Current.Server.MapPath(logFile);

        // Open the log file for append and write the log
        StreamWriter sw = new StreamWriter(logFile, true);
        sw.Write("******************** " + DateTime.Now);
        sw.WriteLine(" ********************");
        if (exc.InnerException != null)
        {
            sw.Write("Inner Exception Type: ");
            sw.WriteLine(exc.InnerException.GetType().ToString());
            sw.Write("Inner Exception: ");
            sw.WriteLine(exc.InnerException.Message);
            sw.Write("Inner Source: ");
            sw.WriteLine(exc.InnerException.Source);
            if (exc.InnerException.StackTrace != null)
                sw.WriteLine("Inner Stack Trace: ");
            sw.WriteLine(exc.InnerException.StackTrace);
        }
        sw.Write("Exception Type: ");
        sw.WriteLine(exc.GetType().ToString());
        sw.WriteLine("Exception: " + exc.Message);
        sw.WriteLine("Source: " + source);
        sw.WriteLine("Stack Trace: ");
        if (exc.StackTrace != null)
            sw.WriteLine(exc.StackTrace);
        sw.WriteLine();
        sw.Close();
    }

    // Notify System Operators about an exception
    public static void NotifySystemOps(Exception exc)
    {
        // Include code for notifying IT system operators
    }
}

Default.aspx

L'exemple suivant fournit la page Default.aspx. Ce fichier fournit trois boutons, chacun d'eux déclenchant une exception différente. Le gestionnaire Page_Error de la page filtre les erreurs spécifiques et gère ces trois exceptions de trois façons différentes. Il fournit également un lien vers un fichier inexistant qui propose un quatrième type d'erreur qui n'est pas gérée sur la page.

<%@ Page Language="C#" %>

<script >
    protected void Submit_Click(object sender, EventArgs e)
    {
        string arg = ((Button)sender).CommandArgument;

        if (arg.Equals("1"))
        {
            // Exception handled on the Generic Error Page
            throw new InvalidOperationException("Invalid click operation?!");
        }
        else if (arg.Equals("2"))
        {
            // Exception handled on the current page
            throw new ArgumentOutOfRangeException("click?!");
        }
        else
        {
            // Exception handled on the Http Error Page (per Web.Config)
            throw new Exception("Generic click problem?!");
        }
    }
    private void Page_Error(object sender, EventArgs e)
    {
        // Get last error from the server
        Exception exc = Server.GetLastError();

        // Filter for a specific kind of exception
        if (exc is ArgumentOutOfRangeException)
        {
            // Give the user some information, but
            // stay on the default page
            Response.Write("<h2>Default Page Error</h2>\n");
            Response.Write( 
                "<p>ArgumentOutOfRange: Your click must have " +
                "been out of range?!</p>\n");
            Response.Write("Return to the <a href='Default.aspx'>" +
                "Default Page</a>\n");

            // Log the exception and notify system operators
            ExceptionUtility.LogException(exc, "DefaultPage");
            ExceptionUtility.NotifySystemOps(exc);

            // Clear the error from the server
            Server.ClearError();

        }
        // Filter for other kinds of exceptions
        else if (exc is InvalidOperationException)
        {
            // Pass the error on to the Generic Error page
            Server.Transfer("GenericErrorPage.aspx", true);
        }
        else
        {
            // Pass the error on to the default global handler
        }
    }
</script>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head >
    <title>Exception Handler Page</title>
</head>
<body>
    <form id="form1" >
    <div>

    <h2>Default Page</h2>
        <p>
            Click this button to create a InvalidOperationException.<br />
            <asp:Button ID="Submit1"  CommandArgument="1" 
                OnClick="Submit_Click" Text="Click 1" />
        </p>
        <p>
            Click this button to create a ArgumentOutOfRangeException.<br />
            <asp:Button ID="Submit2"  CommandArgument="2" 
                OnClick="Submit_Click" Text="Click 2" />
        </p>
        <p>
            Click this button to create a generic Exception.<br />
            <asp:Button ID="Submit3"  CommandArgument="3" 
                OnClick="Submit_Click" Text="Click 3" />
        </p>

        <p>Click this link to attempt to access a non-existent page:<br />
        <a href="NoPage.aspx">NoPage.aspx</a>
    </p>

    </div>
    </form>
</body>
</html>

GenericErrorPage.aspx

L'exemple suivant fournit la page GenericErrorPage.aspx. Cette page crée un message sécurisé qu'elle affiche pour les utilisateurs distants. Pour les utilisateurs locaux (développeurs et testeurs de l'application), la page affiche un rapport d'exceptions complet.

<%@ Page Language="C#" %>

<script >
    protected Exception ex = null;

    protected void Page_Load(object sender, EventArgs e)
    {
        // Get the last error from the server
        Exception ex = Server.GetLastError();

        // Create a safe message
        string safeMsg = "A problem has occurred in the web site. ";

        // Show Inner Exception fields for local access
        if (ex.InnerException != null)
        {
            innerTrace.Text = ex.InnerException.StackTrace;
            InnerErrorPanel.Visible = Request.IsLocal;
            innerMessage.Text = ex.InnerException.Message;
        }
        // Show Trace for local access
        if (Request.IsLocal)
            exTrace.Visible = true;
        else
            ex = new Exception(safeMsg, ex);

        // Fill the page fields
        exMessage.Text = ex.Message;
        exTrace.Text = ex.StackTrace;

        // Log the exception and notify system operators
        ExceptionUtility.LogException(ex, "Generic Error Page");
        ExceptionUtility.NotifySystemOps(ex);

        // Clear the error from the server
        Server.ClearError();
    }
</script>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head >
    <title>Generic Error Page</title>
</head>
<body>
    <form id="form1" >
    <div>

    <h2>Generic Error Page</h2>
    <asp:Panel ID="InnerErrorPanel"  Visible="false">
        <p>
            Inner Error Message:<br />
            <asp:Label ID="innerMessage"  
                Font-Bold="true" Font-Size="Large" /><br />
        </p>
        <pre>
<asp:Label ID="innerTrace"  />
        </pre>
    </asp:Panel>
    <p>
        Error Message:<br />
        <asp:Label ID="exMessage"  
            Font-Bold="true" Font-Size="Large" />
    </p>
    <pre>
<asp:Label ID="exTrace"  visible="false" />
    </pre>

    </div>
    </form>
</body>
</html>

HttpErrorPage.aspx

L'exemple suivant fournit la page HttpErrorPage.aspx. Cette page crée également un message sécurisé qui dépend de la valeur du code d'erreur, qu'elle affiche pour les utilisateurs distants. Pour les utilisateurs locaux, la page affiche un rapport d'exceptions complet.

<%@ Page Language="C#" %>

<script >
    protected HttpException ex = null;

    protected void Page_Load(object sender, EventArgs e)
    {
        ex = (HttpException)Server.GetLastError();
        string safeMsg = String.Empty;

        // Filter for Error Codes and set text
        if (ex.ErrorCode >= 400 && ex.ErrorCode < 500)
        {
            ex = new HttpException
                (ex.ErrorCode, 
                    "Your file could not be found or " +
                    "there was an access problem.", ex);
        }
        else if (ex.ErrorCode > 499)
            ex = new HttpException
                (ex.ErrorCode, 
                    "There was an error on the server.", ex);
        else
            ex = new HttpException
                (ex.ErrorCode, 
                "There was a problem " +
                    "with the web site.", ex);

        // Log the exception and notify system operators
        ExceptionUtility.LogException(ex, "HttpErrorPage");
        ExceptionUtility.NotifySystemOps(ex);

        // Fill the page fields
        exMessage.Text = ex.Message;
        exTrace.Text = ex.StackTrace;

        // Show Inner Exception fields for local access
        if (ex.InnerException != null)
        {
            innerTrace.Text = ex.InnerException.StackTrace;
            InnerErrorPanel.Visible = Request.IsLocal;
            innerMessage.Text = ex.InnerException.Message;
        }
        // Show Trace for local access
        exTrace.Visible = Request.IsLocal;

        // Clear the error from the server
        Server.ClearError();
    }
</script>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head >
    <title>Generic Error Page</title>
</head>
<body>
    <form id="form1" >
    <div>

    <h2>Http Error Page</h2>    
    <asp:Panel ID="InnerErrorPanel"  Visible="false">
        <asp:Label ID="innerMessage"  
            Font-Bold="true" Font-Size="Large" /><br />
        <pre>
<asp:Label ID="innerTrace"  />
        </pre>
    </asp:Panel>
    Error Message:<br />
    <asp:Label ID="exMessage"  
        Font-Bold="true" Font-Size="Large" />
    <pre>
<asp:Label ID="exTrace"  visible="false" />
    </pre>

    </div>
    </form>
</body>
</html>

Voir aussi

Tâches

Comment : gérer les erreurs au niveau de la page

Comment : gérer les erreurs au niveau de l'application

Autres ressources

Gestion des erreurs dans les pages et les applications ASP.NET