Processamento de exceção

Quando um programa é executado, uma série de condições anormais e erros chamados "exceções" podem ocorrer. Isso pode incluir memória insuficiente, erros de alocação de recursos e falha ao localizar arquivos.

A Biblioteca Microsoft Foundation Class usa um esquema de tratamento de exceções modelado de uma forma muito parecida com a proposta do comitê de padrões ANSI para C++. Um manipulador de exceção deve ser configurado, antes de chamar uma função que possa encontrar uma situação anormal. Se a função encontrar uma condição anormal, gerará uma exceção e o controle será passado para o manipulador de exceção.

Várias macros incluídas na Biblioteca Microsoft Foundation Class configurarão os manipuladores de exceção. Várias outras funções globais ajudam a gerar exceções especializadas e encerrar programas, se necessário. Essas macros e funções globais se enquadram nas seguintes categorias:

  • Macros de exceção, que estruturam o manipulador de exceção.

  • Funções geradoras de exceções, que geram exceções de tipos específicos.

  • Funções de término, que terminam o programa.

Para obter exemplos e mais detalhes, confira o artigo Exceções.

Macros de Exceção

Nome Descrição
TRY Designa um bloco de código para processamento de exceção.
CATCH Designa um bloco de código para capturar uma exceção do bloco TRY anterior.
CATCH_ALL Designa um bloco de código para capturar todas as exceções do bloco TRY anterior.
AND_CATCH Designa um bloco de código para capturar tipos adicionais de exceção do bloco TRY anterior.
AND_CATCH_ALL Designa um bloco de código para capturar todos os outros tipos de exceção gerados em um bloco TRY anterior.
END_CATCH Termina o último bloco de código CATCH ou AND_CATCH.
END_CATCH_ALL Termina o último bloco de código CATCH_ALL.
THROW Gera uma exceção especificada.
THROW_LAST Gera a exceção tratada no momento para o próximo manipulador externo.

Funções Geradoras de Exceções

Nome Descrição
AfxThrowArchiveException Gera uma exceção de camada de armazenamento de arquivos.
AfxThrowFileException Gera uma exceção de arquivo.
AfxThrowInvalidArgException Gera uma exceção de argumento inválido.
AfxThrowMemoryException Gera uma exceção de memória.
AfxThrowNotSupportedException Gera uma exceção sem suporte.
AfxThrowResourceException Gera uma exceção de recurso não encontrado do Windows.
AfxThrowUserException Gera uma exceção em uma ação de programa iniciada pelo usuário.

A biblioteca MFC fornece duas funções geradoras de exceções especificamente para exceções OLE:

Funções de Exceção OLE

Nome Descrição
AfxThrowOleDispatchException Gera uma exceção em uma função de automação OLE.
AfxThrowOleException Gera uma exceção OLE.

Para dar suporte a exceções de banco de dados, as classes de banco de dados fornecem duas classes de exceção, CDBException e CDaoException, e funções globais para dar suporte aos tipos de exceção:

Funções de Exceção DAO

Nome Descrição
AfxThrowDAOException Gera um CDaoException a partir de seu próprio código.
AfxThrowDBException Gera um CDBException a partir de seu próprio código.

A biblioteca MFC fornece a função de término a seguir:

Funções de Término

Nome Descrição
AfxAbort Chamado para terminar um aplicativo quando ocorre um erro fatal.

TRY

Configura um bloco TRY.

TRY

Comentários

Um bloco TRY identifica um bloco de código que pode gerar exceções. Essas exceções são tratadas nos seguintes blocos CATCH e AND_CATCH. A recursão é permitida: as exceções podem ser passadas para um bloco TRY externo, ao ignorá-las ou usar a macro THROW_LAST. Termine o bloco TRY com uma macro END_CATCH ou END_CATCH_ALL.

Para saber mais, confira o artigo Exceções.

Exemplo

Confira o exemplo de CATCH.

Requisitos

Cabeçalho: afx.h

CATCH

Define um bloco de código que captura o primeiro tipo de exceção gerado no bloco TRY anterior.

CATCH(exception_class, exception_object_pointer_name)

Parâmetros

exception_class
Especifica o tipo de exceção a ser testado. Para obter uma lista de classes de exceção padrão, confira a classe CException.

exception_object_pointer_name
Especifica um nome para um ponteiro de objeto de exceção, que será criado pela macro. Você pode usar o nome do ponteiro para acessar o objeto de exceção no bloco CATCH. Essa variável é declarada para você.

Comentários

O código de processamento de exceção pode interrogar o objeto de exceção, se apropriado, para obter mais informações sobre a causa específica da exceção. Invoque a macro THROW_LAST para mudar o processamento para o próximo quadro de exceção externa. Termine o bloco TRY com uma macro END_CATCH.

Se exception_class for a classe CException, todos os tipos de exceção serão capturados. Você pode usar a função de membro CObject::IsKindOf para determinar qual exceção específica foi gerada. Uma maneira melhor de capturar vários tipos de exceções é usar instruções sequenciais AND_CATCH, cada uma com um tipo de exceção diferente.

O ponteiro do objeto de exceção é criado pela macro. Você não precisa declarar isso por si mesmo.

Observação

O bloco CATCH é definido como um escopo do C++ entre chaves. Se você declarar variáveis nesse escopo, elas estarão acessíveis somente dentro desse escopo. Isso também se aplica a exception_object_pointer_name.

Para obter mais informações sobre exceções e a macro CATCH, confira o artigo Exceções.

Exemplo

CFile* pFile = NULL;
// Constructing a CFile object with this override may throw
// a CFile exception and won't throw any other exceptions.
// Calling CString::Format() may throw a CMemoryException,
// so we have a catch block for such exceptions, too. Any
// other exception types this function throws will be
// routed to the calling function.
TRY
{
   pFile = new CFile(_T("C:\\WINDOWS\\SYSTEM.INI"),
      CFile::modeRead | CFile::shareDenyNone);
   ULONGLONG dwLength = pFile->GetLength();
   CString str;
   str.Format(_T("Your SYSTEM.INI file is %I64u bytes long.") , dwLength);
   AfxMessageBox(str);
}
CATCH(CFileException, pEx)
{
   // Simply show an error message to the user.
   pEx->ReportError();
}
AND_CATCH(CMemoryException, pEx)
{
   // We can't recover from this memory exception, so we'll
   // just terminate the app without any cleanup. Normally, 
   // an application should do everything it possibly can to
   // clean up properly and not call AfxAbort().
   AfxAbort();
}
END_CATCH
// If an exception occurs in the CFile constructor,
// the language will free the memory allocated by new
// and will not complete the assignment to pFile.
// Thus, our cleanup code needs to test for NULL.
if (pFile != NULL)
{
   pFile->Close();
   delete pFile;
}

CATCH_ALL

Define um bloco de código que captura todos os tipos de exceção gerados no bloco TRY anterior.

CATCH_ALL(exception_object_pointer_name)

Parâmetros

exception_object_pointer_name
Especifica um nome para um ponteiro de objeto de exceção, que será criado pela macro. Você pode usar o nome do ponteiro para acessar o objeto de exceção no bloco CATCH_ALL. Essa variável é declarada para você.

Comentários

O código de processamento de exceção pode interrogar o objeto de exceção, se apropriado, para obter mais informações sobre a causa específica da exceção. Invoque a macro THROW_LAST para mudar o processamento para o próximo quadro de exceção externa. Se você usar CATCH_ALL, termine o bloco TRY com uma macro END_CATCH_ALL.

Observação

O bloco CATCH_ALL é definido como um escopo do C++ entre chaves. Se você declarar variáveis nesse escopo, elas estarão acessíveis somente dentro desse escopo.

Para mais informações sobre exceções, confira o artigo Exceções.

Exemplo

Confira o exemplo de CFile::Abort.

Requisitos

Cabeçalho afx.h

AND_CATCH

Defina um bloco de código para capturar os tipos adicionais de exceção gerados em um bloco TRY anterior.

AND_CATCH(exception_class, exception_object_pointer_name)

Parâmetros

exception_class
Especifica o tipo de exceção a ser testado. Para obter uma lista de classes de exceção padrão, confira a classe CException.

exception_object_pointer_name
Um nome para um ponteiro de objeto de exceção, que será criado pela macro. Você pode usar o nome do ponteiro para acessar o objeto de exceção no bloco AND_CATCH. Essa variável é declarada para você.

Comentários

Use a macro CATCH para capturar um tipo de exceção e, em seguida, a macro AND_CATCH para capturar cada tipo subsequente. Termine o bloco TRY com uma macro END_CATCH.

O código de processamento de exceção pode interrogar o objeto de exceção, se apropriado, para obter mais informações sobre a causa específica da exceção. Chame a macro THROW_LAST no bloco AND_CATCH para deslocar o processamento para o próximo quadro de exceção externa. AND_CATCH marca o final do bloco CATCH ou AND_CATCH anterior.

Observação

O bloco CATCH é definido como escopo do C++ (entre chaves). Se você declarar variáveis nesse escopo, lembre-se que elas estarão acessíveis somente dentro desse escopo. Isso também se aplica à variável exception_object_pointer_name.

Exemplo

Confira o exemplo de CATCH.

Requisitos

Cabeçalho afx.h

AND_CATCH_ALL

Defina um bloco de código para capturar os tipos adicionais de exceção gerados em um bloco TRY anterior.

AND_CATCH_ALL(exception_object_pointer_name)

Parâmetros

exception_object_pointer_name
Um nome para um ponteiro de objeto de exceção, que será criado pela macro. Você pode usar o nome do ponteiro para acessar o objeto de exceção no bloco AND_CATCH_ALL. Essa variável é declarada para você.

Comentários

Use a macro CATCH para capturar um tipo de exceção e, em seguida, a macro AND_CATCH_ALL para capturar todos os outros tipos subsequentes. Se você usar AND_CATCH_ALL, termine o bloco TRY com uma macro END_CATCH_ALL.

O código de processamento de exceção pode interrogar o objeto de exceção, se apropriado, para obter mais informações sobre a causa específica da exceção. Chame a macro THROW_LAST no bloco AND_CATCH_ALL para deslocar o processamento para o próximo quadro de exceção externa. AND_CATCH_ALL marca o final do bloco CATCH ou AND_CATCH_ALL anterior.

Observação

O bloco AND_CATCH_ALL é definido como um escopo do C++ (entre chaves). Se você declarar variáveis nesse escopo, lembre-se que elas estarão acessíveis somente dentro desse escopo.

Requisitos

Cabeçalho afx.h

END_CATCH

Marca o final do último bloco CATCH ou AND_CATCH.

END_CATCH

Comentários

Para obter mais informações sobre a macro END_CATCH, confira o artigo Exceções.

Requisitos

Cabeçalho afx.h

END_CATCH_ALL

Marca o final do último bloco CATCH_ALL88 ou AND_CATCH_ALL.

END_CATCH_ALL

Requisitos

Cabeçalho afx.h

LANÇAMENTO (MFC)

Gera a exceção especificada.

THROW(exception_object_pointer)

Parâmetros

exception_object_pointer
Aponta para um objeto de exceção derivado de CException.

Comentários

THROW interrompe a execução do programa, passando o controle para o bloco CATCH associado no programa. Se você não tiver fornecido o bloco CATCH, o controle será passado para um módulo da Biblioteca Microsoft Foundation Class, que imprime uma mensagem de erro e sai.

Para saber mais, confira o artigo Exceções.

Requisitos

Cabeçalho afx.h

THROW_LAST

Gera a exceção novamente para o próximo bloco CATCH externo.

THROW_LAST()

Comentários

Essa macro permite que você gere uma exceção criada localmente. Se você tentar lançar uma exceção que acabou de capturar, ela normalmente sairá do escopo e será excluída. Com THROW_LAST, a exceção é passada corretamente para o próximo manipulador CATCH.

Para saber mais, confira o artigo Exceções.

Exemplo

Confira o exemplo de CFile::Abort.

Requisitos

Cabeçalho afx.h

AfxThrowArchiveException

Gera uma exceção de camada de armazenamento de arquivos.

void  AfxThrowArchiveException(int cause, LPCTSTR lpszArchiveName);

Parâmetros

causa
Especifica um inteiro que indica o motivo da exceção. Para obter uma lista dos valores possíveis, confira CArchiveException::m_cause.

lpszArchiveName
Aponta para uma cadeia de caracteres que contém o nome do objeto CArchive que causou a exceção (se disponível).

Requisitos

Cabeçalho afx.h

AfxThrowFileException

Gera uma exceção de arquivo.

void AfxThrowFileException(
    int cause,
    LONG lOsError = -1,
    LPCTSTR lpszFileName = NULL);

Parâmetros

causa
Especifica um inteiro que indica o motivo da exceção. Para obter uma lista dos valores possíveis, confira CFileException::m_cause.

lOsError
Contém o número do erro do sistema operacional (se disponível) que indica o motivo da exceção. Confira o manual do sistema operacional para obter uma lista de códigos de erro.

lpszFileName
Aponta para uma cadeia de caracteres que contém o nome do arquivo que causou a exceção (se disponível).

Comentários

Você é responsável por determinar a causa com base no código de erro do sistema operacional.

Requisitos

Cabeçalho afx.h

AfxThrowInvalidArgException

Gera uma exceção de argumento inválido.

Sintaxe

void AfxThrowInvalidArgException( );

Comentários

Essa função é chamada quando argumentos inválidos são usados.

Requisitos

Cabeçalho: afx.h

AfxThrowMemoryException

Gera uma exceção de memória.

void AfxThrowMemoryException();

Comentários

Chame essa função em caso de falha nas chamadas para os alocadores de memória do sistema subjacentes (como malloc e a função GlobalAlloc do Windows). Você não precisa chamá-la para new, pois new gerará uma exceção de memória automaticamente, em caso de falha na alocação de memória.

Requisitos

Cabeçalho afx.h

AfxThrowNotSupportedException

Gera uma exceção que é o resultado de uma solicitação para um recurso sem suporte.

void AfxThrowNotSupportedException();

Requisitos

Cabeçalho afx.h

AfxThrowResourceException

Gera uma exceção de recurso.

void  AfxThrowResourceException();

Comentários

Essa função normalmente é chamada quando um recurso do Windows não pode ser carregado.

Requisitos

Cabeçalho afx.h

AfxThrowUserException

Gera uma exceção para interromper uma operação de usuário final.

void AfxThrowUserException();

Comentários

Essa função normalmente é chamada imediatamente depois que AfxMessageBox relatou um erro ao usuário.

Requisitos

Cabeçalho afx.h

AfxThrowOleDispatchException

Use essa função para gerar uma exceção em uma função de automação OLE.

void AFXAPI AfxThrowOleDispatchException(
    WORD wCode ,
    LPCSTR lpszDescription,
    UINT nHelpID = 0);

void AFXAPI AfxThrowOleDispatchException(
    WORD wCode,
    UINT nDescriptionID,
    UINT nHelpID = -1);

Parâmetros

wCode
Um código de erro específico do aplicativo.

lpszDescription
Descrição verbal do erro.

nDescriptionID
ID do recurso para a descrição do erro verbal.

nHelpID
Um contexto de ajuda para o arquivo de ajuda do aplicativo (.HLP).

Comentários

As informações fornecidas para essa função podem ser exibidas pelo aplicativo de condução (Microsoft Visual Basic ou outro aplicativo cliente de automação OLE).

Exemplo

// Sort is method of automation class CStrArrayDoc
long CStrArrayDoc::Sort(VARIANT* vArray)
{
   USES_CONVERSION;

   // Type check VARIANT parameter. It should contain a BSTR array
   // passed by reference. The array must be passed by reference; it is
   // an in-out-parameter.

   // throwing COleDispatchException allows the EXCEPINFO structure of 
   // IDispatch::Invoke() to set
   if (V_VT(vArray) != (VT_ARRAY | VT_BSTR))
      AfxThrowOleDispatchException(1001,
         _T("Type Mismatch in Parameter. Pass a string array by reference"));

   // ...
   // ...

   return 0;
}

Requisitos

Cabeçalho afx.h

AfxThrowOleException

Cria um objeto do tipo COleException e gera uma exceção.

void AFXAPI AfxThrowOleException(SCODE sc);
void AFXAPI AfxThrowOleException(HRESULT hr);

Parâmetros

sc
Um código de status OLE que indica o motivo da exceção.

RH
Identificador para um código de resultado que indica o motivo da exceção.

Comentários

A versão que usa um HRESULT como argumento converte esse código de resultado no SCODE correspondente. Para obter mais informações sobre o HRESULT e SCODE, confira Estrutura de códigos de erro COM no SDK do Windows.

Requisitos

Cabeçalho afxdao.h

AfxThrowDaoException

Chame essa função para gerar uma exceção do tipo CDaoException a partir de seu próprio código.

void AFXAPI AfxThrowDaoException(
    int nAfxDaoError = NO_AFX_DAO_ERROR,
    SCODE scode = S_OK);

Parâmetros

nAfxDaoError
Um valor inteiro que representa um código de erro estendido do DAO, que pode ser um dos valores listados em CDaoException::m_nAfxDaoError.

scode
Um código de erro OLE do DAO, do tipo SCODE. Para obter informações, confira CDaoException::m_scode.

Comentários

A estrutura também chama AfxThrowDaoException. Na chamada, você pode passar um dos parâmetros ou ambos. Por exemplo, se você quiser gerar um dos erros definidos em CDaoException::nAfxDaoError, mas não se importar com o parâmetro scode, passe um código válido no parâmetro nAfxDaoError e aceite o valor padrão para scode.

Para obter informações sobre exceções relacionadas às classes MFC DAO, confira a classe CDaoException neste manual e o artigo Exceções: Exceções de Banco de Dados.

Requisitos

Cabeçalho afxdb.h

AfxThrowDBException

Chame essa função para gerar uma exceção do tipo CDBException a partir de seu próprio código.

void AfxThrowDBException(
    RETCODE nRetCode,
    CDatabase* pdb,
    HSTMT hstmt);

Parâmetros

nRetCode
Um valor do tipo RETCODE, que define o tipo de erro que fez com que a exceção fosse gerada.

pdb
Um ponteiro para o objeto CDatabase, que representa a conexão de fonte de dados à qual a exceção está associada.

HSTMT
Um identificador ODBC HSTMT que especifica o identificador da instrução ao qual a exceção está associada.

Comentários

A estrutura chama AfxThrowDBException quando recebe um RETCODE ODBC de uma chamada para uma função de API ODBC e interpreta o RETCODE como uma condição excepcional, em vez de um erro esperado. Por exemplo, uma operação de acesso a dados pode falhar devido a um erro de leitura de disco.

Para obter informações sobre os valores RETCODE definidos pelo ODBC, confira o Capítulo 8, "Recuperação de informações de status e erro", no SDK do Windows. Para obter informações sobre extensões da biblioteca MFC para esses códigos, confira a classe CDBException.

Requisitos

Cabeçalho afx.h

AfxAbort

A função de término padrão fornecida pela biblioteca MFC.

void  AfxAbort();

Comentários

AfxAbort é chamado internamente pelas funções de membro da biblioteca MFC, quando ocorre um erro fatal, como uma exceção não capturada que não pode ser tratada. Você pode chamar AfxAbort no caso raro em que encontrar um erro catastrófico do qual não é possível se recuperar.

Exemplo

Confira o exemplo de CATCH.

Requisitos

Cabeçalho afx.h

Confira também

Macros e Globais
Classe CException
Classe CInvalidArgException