Compartilhar via


Tratamento de exceção

As diretrizes a seguir ajudam a garantir que sua biblioteca manipula exceções apropriadamente.

Não manipular erros ao detectar exceções não específico, como, por exemplo, System. Exception, System. SystemException e assim por diante, no código de estrutura.

Você pode capturar exceções quando a finalidade da captura da exceção for relançar ou transferir a exceção para um thread diferente. O exemplo de código a seguir demonstra a manipulação incorreta da exceção.

Public Class BadExceptionHandlingExample1

    Public Sub DoWork()
        ' Do some work that might throw exceptions.
    End Sub

    Public Sub MethodWithBadHandler()
        Try
            DoWork()
        Catch e As Exception
            ' Handle the exception and 
            ' continue executing.
        End Try
    End Sub
End Class
public class BadExceptionHandlingExample1
{
    public void DoWork()
    {
        // Do some work that might throw exceptions.
    }
    public void MethodWithBadHandler()
    {
        try
        {
            DoWork();
        }
        catch (Exception e)
        {
            // Handle the exception and
            // continue executing.
        }
    }
}
public ref class BadExceptionHandlingExample1
{
public:
    void DoWork()
    {
        // Do some work that might throw exceptions.
    }

    void MethodWithBadHandler()
    {
        try
        {
            DoWork();
        }
        catch (Exception^ e)
        {
            // Handle the exception and
            // continue executing.
        }
    }
};

Evite a manipulação de erros captura exceções não específico, como, por exemplo, System. Exception, System. SystemException e assim por diante, no código do aplicativo. Há casos, quando o tratamento de erros de aplicativos é aceitável, mas tais casos são raros.

Um aplicativo não deve lidar com exceções que podem resultar em um estado inesperado ou explorável. Se você não pode prever todas as possíveis causas de uma exceção e certificar-se de que um código mal-intencionado não poderá explorar o estado resultante do aplicativo, você deve permitir que o aplicativo encerre, em vez de tratar a exceção.

Não exclua quaisquer exceções especiais quando a finalidade de transferência de exceções.

Em vez de criar listas de exceções especiais no seu catch cláusulas, você deve capturar apenas essas exceções que você pode manipular legitimamente. Exceções que você não pode manipular não devem ser tratadas como casos especiais minúsculas em especial, nos manipuladores de exceção de não-específica. O exemplo de código a seguir demonstra incorretamente testes para exceções especiais para fins de relançá-los.

Public Class BadExceptionHandlingExample2

    Public Sub DoWork()
        ' Do some work that might throw exceptions.
    End Sub

    Public Sub MethodWithBadHandler()
        Try
            DoWork()
        Catch e As Exception
            If TypeOf e Is StackOverflowException Or _
               TypeOf e Is OutOfMemoryException Then
                Throw
            End If
        End Try
    End Sub
End Class
public class BadExceptionHandlingExample2
{
    public void DoWork()
    {
        // Do some work that might throw exceptions.
    }
    public void MethodWithBadHandler()
    {
        try
        {
            DoWork();
        }
        catch (Exception e)
        {
            if (e is StackOverflowException ||
                e is OutOfMemoryException)
                throw;
            // Handle the exception and
            // continue executing.
        }
    }
}
public ref class BadExceptionHandlingExample2
{
public:
    void DoWork()
    {
        // Do some work that might throw exceptions.
    }

    void MethodWithBadHandler()
    {
        try
        {
            DoWork();
        }
        catch (Exception^ e)
        {
            if (e->GetType() == StackOverflowException::typeid ||
                e->GetType() == OutOfMemoryException::typeid)
                throw;
            // Handle the exception and
            // continue executing.
        }
    }
};

Considere a possibilidade de capturar exceções específicas quando você compreende por que será lançada em um determinado contexto.

Você deve capturar apenas essas exceções que você pode recuperar. Por exemplo, um FileNotFoundException que os resultados de uma tentativa de abrir um arquivo inexistente podem ser manipulados por um aplicativo porque ele pode comunicar-se o problema para o usuário e permitir que o usuário especifique um nome de arquivo diferente ou criar o arquivo. Uma solicitação para abrir um arquivo que gera um ExecutionEngineException não devem ser tratados como a causa subjacente da exceção não pode ser conhecida com qualquer grau de certeza e o aplicativo não pode garantir que é seguro continuar a executar.

Não use em exagero catch. Exceções freqüentemente devem ter permissão para se propagar até a pilha de chamadas.

Capturando exceções que você não pode tratar legitimamente oculta informações críticas de depuração.

Usar o try-finally e evite usar o try-catch para o código de limpeza. No código de exceção bem-escrito, try-finally é muito mais comum que try-catch.

A finalidade de um catch cláusula é para permitir que você manipular exceções (por exemplo, fazendo um erro não fatal). A finalidade de um finally cláusula é para permitir que você executar o código de limpeza, independentemente se ocorreu uma exceção. Se você alocar recursos caros ou limitados, como, por exemplo, conexões de banco de dados ou fluxos, você deve colocar o código lançá-los dentro de um finally bloco.

Prefira usar um throw vazio quando capturar e relançar a exceção. Esta é a melhor maneira de preservar a pilha de chamadas de exceção.

O exemplo de código a seguir mostra um método que pode lançar uma exceção. Esse método é referenciado nos exemplos posteriores.

Public Sub DoWork(ByVal anObject As Object)
    ' Do some work that might throw exceptions.
    If (anObject = Nothing) Then
        Throw New ArgumentNullException("anObject", "Specify a non-null argument.")
    End If
    ' Do work with o.
End Sub
public void DoWork(Object anObject)
{
    // Do some work that might throw exceptions.
    if (anObject == null)
    {
        throw new ArgumentNullException("anObject",
            "Specify a non-null argument.");
    }
    // Do work with o.
}
public:

    void DoWork(Object^ anObject)
    {
        // Do some work that might throw exceptions.
        if (anObject == nullptr)
        {
            throw gcnew ArgumentNullException("anObject",
                "Specify a non-null argument.");
        }
        // Do work with o.
    }

O exemplo de código a seguir demonstra a capturar uma exceção e especificação incorreta quando relançar a exceção. Isso faz com que o rastreamento de pilha apontar para o re-throw como o local do erro, em vez de apontar para o DoWork método.

        Public Sub MethodWithBadCatch(ByVal anObject As Object)
            Try
                DoWork(anObject)

            Catch e As ArgumentNullException
                System.Diagnostics.Debug.Write(e.Message)
                ' This is wrong.
                Throw e
                ' Should be this:
                ' throw
            End Try
        End Sub

public void MethodWithBadCatch(Object anObject)
{
    try
    {
        DoWork(anObject);
    }
    catch (ArgumentNullException e)
    {
       System.Diagnostics.Debug.Write(e.Message);
       // This is wrong.
       throw e;
       // Should be this:
       // throw;
    }
}
void MethodWithBadCatch(Object^ anObject)
{
    try
    {
        DoWork(anObject);
    }
    catch (ArgumentNullException^ e)
    {
       System::Diagnostics::Debug::Write(e->Message);
       // This is wrong.
       throw e;
       // Should be this:
       // throw;
    }
}

Não lidar com exceções não compatível com CLS (exceções não derivar de System. Exception) usando um bloco catch sem parâmetros. Idiomas que oferecem suporte a exceções que não são derivadas de exceção são livres para manipular essas exceções de conformidade não-CLS.

A.NET Framework versão 2.0 envolve as exceções não compatível com CLS em uma classe derivada de Exception.

Portions Copyright 2005 Microsoft Corporation. Todos os direitos reservados.

Portions Copyright Addison-Wesley Corporation. Todos os direitos reservados.

Para obter mais informações sobre as diretrizes de design, consulte a "diretrizes de Design do Framework: Convenções, idiomas e padrões de reutilizável.Bibliotecas de rede" catálogo por Krzysztof Cwalina e Brad Abrams, publicado pela Addison-Wesley, 2005.

Consulte também

Outros recursos

Diretrizes de Design para desenvolvimento bibliotecas de classe

Diretrizes de design para exceções