Exibição de uma página de erro personalizada (C#)

por Scott Mitchell

O que o usuário vê quando ocorre um erro de runtime em um aplicativo Web ASP.NET? A resposta depende de como a configuração customErrors> do <site. Por padrão, os usuários são mostrados em uma tela amarela sem êxito, proclamando que ocorreu um erro de runtime. Este tutorial mostra como personalizar essas configurações para exibir uma página de erro personalizada esteticamente agradável que corresponda à aparência do seu site.

Introdução

Em um mundo perfeito, não haveria erros em tempo de execução. Os programadores escreveriam código com um bug e com validação robusta de entrada do usuário, e recursos externos, como servidores de banco de dados e servidores de email, nunca ficariam offline. É claro que, na realidade, os erros são inevitáveis. As classes no .NET Framework sinalizam um erro lançando uma exceção. Por exemplo, chamar o método Open de um objeto SqlConnection estabelece uma conexão com o banco de dados especificado por uma cadeia de conexão. No entanto, se o banco de dados estiver inativo ou se as credenciais na cadeia de conexão forem inválidas, o método Open gerará um SqlException. As exceções podem ser tratadas pelo uso de try/catch/finally blocos. Se o código dentro de um try bloco gerar uma exceção, o controle será transferido para o bloco catch apropriado em que o desenvolvedor pode tentar se recuperar do erro. Se não houver nenhum bloco catch correspondente ou se o código que gerou a exceção não estiver em um bloco try, a exceção percolará a pilha de chamadas em pesquisa de try/catch/finally blocos.

Se a exceção chegar até o ASP.NET runtime sem ser manipulada, o HttpApplicationevento da Error classe será gerado e a página de erro configurada será exibida. Por padrão, ASP.NET exibe uma página de erro que é carinhosamente conhecida como YSOD ( Tela Amarela da Morte ). Há duas versões do YSOD: uma mostra os detalhes da exceção, um rastreamento de pilha e outras informações úteis para os desenvolvedores depurarem o aplicativo (consulte a Figura 1); o outro simplesmente afirma que houve um erro em tempo de execução (consulte a Figura 2).

Os detalhes da exceção YSOD são bastante úteis para desenvolvedores que depuram o aplicativo, mas mostrar um YSOD para usuários finais é brega e não profissional. Em vez disso, os usuários finais devem ser levados para uma página de erro que mantenha a aparência do site com uma prosa mais amigável descrevendo a situação. A boa notícia é que criar uma página de erro personalizada é muito fácil. Este tutorial começa com uma olhada no ASP. Páginas de erro diferentes do NET. Em seguida, ele mostra como configurar o aplicativo Web para mostrar aos usuários uma página de erro personalizada diante de um erro.

Examinando os três tipos de páginas de erro

Quando uma exceção sem tratamento surge em um aplicativo ASP.NET um dos três tipos de páginas de erro é exibido:

  • A página de erro Tela Amarela dos Detalhes da Exceção da Morte,
  • A página de erro Tela Amarela de Morte do Erro de Runtime ou
  • Uma página de erro personalizada

A página de erro com a qual os desenvolvedores estão mais familiarizados é o YSOD de Detalhes da Exceção. Por padrão, essa página é exibida para usuários que estão visitando localmente e, portanto, é a página que você vê quando ocorre um erro ao testar o site no ambiente de desenvolvimento. Como o nome indica, o YSOD de Detalhes da Exceção fornece detalhes sobre a exceção : o tipo, a mensagem e o rastreamento de pilha. Além disso, se a exceção tiver sido gerada pelo código na classe code-behind da página ASP.NET e se o aplicativo estiver configurado para depuração, o YSOD de Detalhes da Exceção também mostrará essa linha de código (e algumas linhas de código acima e abaixo dela).

A Figura 1 mostra a página Detalhes da Exceção YSOD. Observe a URL na janela de endereço do navegador: http://localhost:62275/Genre.aspx?ID=foo. Lembre-se de que a Genre.aspx página lista as revisões de livro em um gênero específico. Ele requer que GenreId o valor (um uniqueidentifier) seja passado pela querystring; por exemplo, a URL apropriada para exibir as revisões de ficção é Genre.aspx?ID=7683ab5d-4589-4f03-a139-1c26044d0146. Se um valor não foruniqueidentifier passado por meio da querystring (como "foo") uma exceção será gerada.

Observação

Para reproduzir esse erro no aplicativo Web de demonstração disponível para download, você pode visitar Genre.aspx?ID=foo diretamente ou clicar no link "Gerar um erro de runtime" em Default.aspx.

Observe as informações de exceção apresentadas na Figura 1. A mensagem de exceção "Falha na conversão ao converter de uma cadeia de caracteres em uniqueidentifier" está presente na parte superior da página. O tipo da exceção, System.Data.SqlClient.SqlException, também está listado. Há também o rastreamento de pilha.

Captura de tela que mostra os detalhes da exceção YSOD que incluem informações sobre a exceção.

Figura 1: Os detalhes da exceção YSOD incluem informações sobre a exceção
(Clique para exibir a imagem em tamanho real)

O outro tipo de YSOD é o Erro de Runtime YSOD e é mostrado na Figura 2. O Erro de Runtime YSOD informa ao visitante que ocorreu um erro em tempo de execução, mas não inclui nenhuma informação sobre a exceção que foi gerada. (No entanto, ele fornece instruções sobre como tornar os detalhes do erro acessível modificando o Web.config arquivo, que faz parte do que faz com que tal YSOD pareça não profissional.)

Por padrão, o Erro de Runtime YSOD é mostrado aos usuários que visitam remotamente (por meio http://www.yoursite.comde ), conforme evidenciado pela URL na barra de endereços do navegador na Figura 2: http://httpruntime.web703.discountasp.net/Genre.aspx?ID=foo. As duas telas YSOD diferentes existem porque os desenvolvedores estão interessados em saber os detalhes do erro, mas essas informações não devem ser mostradas em um site ao vivo, pois podem revelar possíveis vulnerabilidades de segurança ou outras informações confidenciais para qualquer pessoa que visite seu site.

Observação

Se você estiver acompanhando e estiver usando DiscountASP.NET como seu host da Web, poderá observar que o Erro de Runtime YSOD não é exibido ao visitar o site ao vivo. Isso ocorre porque DiscountASP.NET tem seus servidores configurados para mostrar os Detalhes da Exceção YSOD por padrão. A boa notícia é que você pode substituir esse comportamento padrão adicionando uma <customErrors> seção ao arquivo Web.config . A seção "Configurando qual página de erro é exibida" examina a <customErrors> seção em detalhes.

Captura de tela que mostra o erro de runtime YSOD não inclui nenhum detalhe de erro.

Figura 2: o erro de runtime YSOD não inclui detalhes do erro
(Clique para exibir a imagem em tamanho real)

O terceiro tipo de página de erro é a página de erro personalizada, que é uma página da Web que você cria. O benefício de uma página de erro personalizada é que você tem controle total sobre as informações que são exibidas ao usuário junto com a aparência da página; a página de erro personalizada pode usar o mesmo master página e estilos que suas outras páginas. A seção "Usando uma página de erro personalizada" explica como criar uma página de erro personalizada e configurá-la para exibição no caso de uma exceção sem tratamento. A Figura 3 oferece um pico sorrateiro desta página de erro personalizada. Como você pode ver, a aparência da página de erro é muito mais profissional do que qualquer uma das Telas Amarelas da Morte mostradas nas Figuras 1 e 2.

Captura de tela que mostra uma página de erro personalizada que demonstra uma aparência mais personalizada.

Figura 3: Uma página de erro personalizada oferece uma aparência mais personalizada
(Clique para exibir a imagem em tamanho real)

Reserve um momento para inspecionar a barra de endereços do navegador na Figura 3. Observe que a barra Endereço mostra a URL da página de erro personalizada (/ErrorPages/Oops.aspx). Nas Figuras 1 e 2, as Telas Amarelas da Morte são mostradas na mesma página da qual o erro se originou (Genre.aspx). A página de erro personalizada é passada para a URL da página em que o erro ocorreu por meio do aspxerrorpath parâmetro querystring.

Configurando qual página de erro é exibida

Qual das três páginas de erro possíveis é exibida é baseada em duas variáveis:

  • As informações de configuração na <customErrors> seção e
  • Se o usuário está visitando o site local ou remotamente.

A <customErrors> seção em Web.config tem dois atributos que afetam qual página de erro é mostrada: defaultRedirect e mode. O atributo defaultRedirect é opcional. Se fornecido, ele especifica a URL da página de erro personalizada e indica que a página de erro personalizada deve ser mostrada em vez do erro de runtime YSOD. O mode atributo é necessário e aceita um dos três valores: On, Offou RemoteOnly. Esses valores têm o seguinte comportamento:

  • On – indica que a página de erro personalizada ou o Erro de Runtime YSOD é mostrado a todos os visitantes, independentemente de serem locais ou remotos.
  • Off – especifica que os Detalhes da Exceção YSOD são exibidos para todos os visitantes, independentemente de serem locais ou remotos.
  • RemoteOnly – indica que a página de erro personalizada ou o Erro de Runtime YSOD é mostrado aos visitantes remotos, enquanto o YSOD de Detalhes da Exceção é mostrado aos visitantes locais.

A menos que você especifique o contrário, ASP.NET age como se você tivesse definido o atributo RemoteOnly mode como e não tivesse especificado um defaultRedirect valor. Em outras palavras, o comportamento padrão é que o YSOD detalhes da exceção é exibido para visitantes locais, enquanto o erro de runtime YSOD é mostrado aos visitantes remotos. Você pode substituir esse comportamento padrão adicionando uma <customErrors> seção ao do aplicativo Web Web.config file.

Usando uma página de erro personalizada

Cada aplicativo Web deve ter uma página de erro personalizada. Ele fornece uma alternativa mais profissional ao Erro de Runtime YSOD, é fácil de criar e configurar o aplicativo para usar a página de erro personalizada leva apenas alguns instantes. A primeira etapa é criar a página de erro personalizada. Adicionei uma nova pasta ao aplicativo Book Reviews chamado ErrorPages e adicionei a ela uma nova página ASP.NET chamada Oops.aspx. Faça com que a página use o mesmo master página que o restante das páginas em seu site para que ela herde automaticamente a mesma aparência.

Captura de tela que realça a nova pasta ErrorPages e o arquivo Oops ot a s p x associado.

Figura 4: Criar uma página de erro personalizada

Em seguida, passe alguns minutos criando o conteúdo para a página de erro. Criei uma página de erro personalizada bastante simples com uma mensagem indicando que houve um erro inesperado e um link de volta para a home page do site.

Captura de tela que mostra a página de erro personalizada e a mensagem associada.

Figura 5: projetar sua página de erro personalizada
(Clique para exibir a imagem em tamanho real)

Com a página de erro concluída, configure o aplicativo Web para usar a página de erro personalizada em vez do Erro de Runtime YSOD. Isso é feito especificando a URL da página de erro no <customErrors> atributo da defaultRedirect seção. Adicione a seguinte marcação ao arquivo do Web.config aplicativo:

<configuration>
    ...

    <system.web>
        <customErrors mode="RemoteOnly"
                      defaultRedirect="~/ErrorPages/Oops.aspx" />

        ...
    </system.web>
</configuration>

A marcação acima configura o aplicativo para mostrar o YSOD detalhes de exceção para os usuários que visitam localmente, enquanto usa a página de erro personalizada Oops.aspx para os usuários que visitam remotamente. Para ver isso em ação, implante seu site no ambiente de produção e visite a página Genre.aspx no site ao vivo com um valor de querystring inválido. Você deve ver a página de erro personalizada (consulte a Figura 3).

Para verificar se a página de erro personalizada é mostrada apenas para usuários remotos, visite a Genre.aspx página com uma consulta inválida do ambiente de desenvolvimento. Você ainda deverá ver os Detalhes da Exceção YSOD (consulte a Figura 1). A RemoteOnly configuração garante que os usuários que visitam o site no ambiente de produção vejam a página de erro personalizada enquanto os desenvolvedores que trabalham localmente continuam a ver os detalhes da exceção.

Notificando desenvolvedores e detalhes de erro de registro em log

Erros que ocorrem no ambiente de desenvolvimento foram causados pelo desenvolvedor sentado em seu computador. Ela recebe as informações da exceção no YSOD detalhes da exceção e sabe quais etapas estava executando quando o erro ocorreu. Mas quando ocorre um erro na produção, o desenvolvedor não tem conhecimento de que ocorreu um erro, a menos que o usuário final que visita o site tenha tempo para relatar o erro. E mesmo que o usuário saia do seu caminho para alertar a equipe de desenvolvimento de que ocorreu um erro, sem saber o tipo de exceção, a mensagem e o rastreamento de pilha, pode ser difícil diagnosticar a causa do erro, muito menos corrigi-lo.

Por esses motivos, é fundamental que qualquer erro no ambiente de produção seja registrado em algum repositório persistente (como um banco de dados) e que os desenvolvedores sejam alertados sobre esse erro. A página de erro personalizada pode parecer um bom lugar para fazer esse registro em log e notificação. Infelizmente, a página de erro personalizada não tem acesso aos detalhes do erro e, portanto, não pode ser usada para registrar essas informações. A boa notícia é que há várias maneiras de interceptar os detalhes do erro e registrá-los, e os próximos três tutoriais exploram este tópico com mais detalhes.

Usando diferentes páginas de erro personalizadas para diferentes status de erro HTTP

Quando uma exceção é gerada por uma página ASP.NET e não é tratada, a exceção percola até o runtime ASP.NET, que exibe a página de erro configurada. Se uma solicitação entrar no mecanismo de ASP.NET, mas não puder ser processada por algum motivo - talvez o arquivo solicitado não seja encontrado ou permissões de leitura tenham sido desabilitadas para o arquivo - o mecanismo de ASP.NET gerará um HttpException. Essa exceção, como exceções geradas de ASP.NET páginas, aumenta até o runtime, fazendo com que a página de erro apropriada seja exibida.

O que isso significa para o aplicativo Web em produção é que, se um usuário solicitar uma página que não foi encontrada, ele verá a página de erro personalizada. A Figura 6 mostra esse exemplo. Como a solicitação é para uma página inexistente (NoSuchPage.aspx), um HttpException é gerado e a página de erro personalizada é exibida (observe a referência a NoSuchPage.aspx no aspxerrorpath parâmetro querystring).

Captura de tela que mostra como o runtime do A SP dot NET exibe a página de erro configurada.

Figura 6: O runtime do ASP.NET exibe a página de erro configurada em resposta a uma solicitação inválida (clique para exibir a imagem em tamanho real)

Por padrão, todos os tipos de erros fazem com que a mesma página de erro personalizada seja exibida. No entanto, você pode especificar uma página de erro personalizada diferente para um código HTTP status específico usando <error> elementos filhos na <customErrors> seção . Por exemplo, para ter uma página de erro diferente exibida no caso de um erro de página não encontrado, que tem um código http status de 404, atualize a <customErrors> seção para incluir a seguinte marcação:

<customErrors mode="RemoteOnly" defaultRedirect="~/ErrorPages/Oops.aspx">
    <error statusCode="404" redirect="~/ErrorPages/404.aspx" />
</customErrors>

Com essa alteração em vigor, sempre que um usuário que estiver visitando remotamente solicitar um recurso ASP.NET que não existe, ele será redirecionado para a 404.aspx página de erro personalizada em vez de Oops.aspx. Como ilustra a Figura 7 , a 404.aspx página pode incluir uma mensagem mais específica do que a página de erro personalizada geral.

Observação

Confira 404 Páginas de Erro, mais uma vez para obter diretrizes sobre como criar 404 páginas de erro efetivas.

Captura de tela que mostra a página de erro 4 O 4 personalizada.

Figura 7: a página de erro personalizada 404 exibe uma mensagem mais direcionada do que Oops.aspx
(Clique para exibir a imagem em tamanho real)

Como você sabe que a 404.aspx página só é acessada quando o usuário faz uma solicitação para uma página que não foi encontrada, você pode aprimorar essa página de erro personalizada para incluir a funcionalidade para ajudar o usuário a resolver esse tipo específico de erro. Por exemplo, você pode criar uma tabela de banco de dados que mapeia URLs incorretas conhecidas para boas URLs e, em seguida, fazer com que a 404.aspx página de erro personalizada execute uma consulta nessa tabela e sugerir páginas que o usuário possa estar tentando acessar.

Observação

A página de erro personalizada só é exibida quando uma solicitação é feita a um recurso manipulado pelo mecanismo de ASP.NET. Como discutimos no tutorial Principais Diferenças entre o IIS e o servidor de desenvolvimento ASP.NET , o servidor Web pode lidar com determinadas solicitações em si. Por padrão, o servidor Web do IIS processa solicitações de conteúdo estático, como imagens e arquivos HTML, sem invocar o mecanismo de ASP.NET. Consequentemente, se o usuário solicitar um arquivo de imagem inexistente, ele receberá de volta a mensagem de erro padrão do IIS 404 em vez de ASP. Página de erro configurada do NET.

Resumo

Quando ocorre uma exceção sem tratamento em um aplicativo ASP.NET, o usuário é mostrado em uma das três páginas de erro: a Tela Amarela de Morte dos Detalhes da Exceção; o Erro de Runtime Tela Amarela da Morte; ou uma página de erro personalizada. Qual página de erro é exibida depende da configuração do <customErrors> aplicativo e se o usuário está visitando local ou remotamente. O comportamento padrão é mostrar o YSOD de Detalhes da Exceção para visitantes locais e o Erro de Runtime YSOD para visitantes remotos.

Embora o Erro de Runtime YSOD oculte informações de erro potencialmente confidenciais do usuário que está visitando o site, ele interrompe a aparência do seu site e faz seu aplicativo parecer um bug. Uma abordagem melhor é usar uma página de erro personalizada, que envolve criar e projetar a página de erro personalizada e especificar sua URL no <customErrors> atributo da defaultRedirect seção. Você pode até mesmo ter várias páginas de erro personalizadas para diferentes status de erro HTTP.

A página de erro personalizada é a primeira etapa de uma estratégia abrangente de tratamento de erros para um site em produção. Alertar o desenvolvedor sobre o erro e registrar seus detalhes também são etapas importantes. Os próximos três tutoriais exploram técnicas para notificação de erro e registro em log.

Programação feliz!

Leitura Adicional

Para obter mais informações sobre os tópicos discutidos neste tutorial, consulte os seguintes recursos: