Procesamiento de excepciones

Cuando se ejecuta un programa, se puede producir una serie de condiciones y errores anómalos denominados "excepciones". Estos pueden incluir quedarse sin memoria, errores de asignación de recursos y errores de búsqueda de archivos.

La biblioteca MFC (Microsoft Foundation Class) usa un esquema de control de excepciones que se modela estrechamente de acuerdo con el propuesto por el comité de estándares ANSI para C++. Se debe configurar un controlador de excepciones antes de llamar a una función que pueda encontrarse con una situación anómala. Si la función encuentra una condición anómala, arroja una excepción y se pasa el control al controlador de excepciones.

Varias macros incluidas con la biblioteca MFC (Microsoft Foundation Class) configurarán controladores de excepciones. Una serie de otras funciones globales ayuda a producir excepciones especializadas y finalizar programas, si es necesario. Estas macros y funciones globales se dividen en las siguientes categorías:

  • Macros de excepción, que estructuran el controlador de excepciones.

  • Funciones de inicio de excepción, que generan excepciones de tipos específicos.

  • Funciones de finalización, que provocan la finalización del programa.

Para obtener ejemplos y más detalles, consulte el artículo Excepciones.

Macros de excepción

Nombre Descripción
TRY Designa un bloque de código para el procesamiento de excepciones.
CATCH Designa un bloque de código para detectar una excepción del bloque TRY anterior.
CATCH_ALL Designa un bloque de código para detectar todas las excepciones del bloque TRY anterior.
AND_CATCH Designa un bloque de código para detectar tipos de excepciones adicionales del bloque TRY anterior.
AND_CATCH_ALL Designa un bloque de código para detectar todos los otros tipos de excepciones adicionales arrojados en un bloque TRY anterior.
END_CATCH Finaliza el último bloque de código CATCH o AND_CATCH.
END_CATCH_ALL Finaliza el último bloque de código CATCH_ALL.
THROW Produce una excepción especificada.
THROW_LAST Inicia la excepción controlada actualmente en el siguiente controlador externo.

Funciones que pueden provocar excepciones

Nombre Descripción
AfxThrowArchiveException Produce una excepción de almacenamiento de archivo.
AfxThrowFileException Produce una excepción de archivo.
AfxThrowInvalidArgException Produce una excepción de argumento no válida.
AfxThrowMemoryException Produce una excepción de memoria.
AfxThrowNotSupportedException Produce una excepción no admitida.
AfxThrowResourceException Produce una excepción de recurso de Windows no encontrado.
AfxThrowUserException Produce una excepción en una acción de programa iniciada por el usuario.

MFC proporciona dos funciones que producen excepciones específicamente para excepciones de OLE:

Funciones de excepción de OLE

Nombre Descripción
AfxThrowOleDispatchException Produce una excepción dentro de una función de automatización de OLE.
AfxThrowOleException Produce una excepción de OLE.

Para admitir excepciones de base de datos, las clases de base de datos proporcionan dos clases de excepción, CDBException y CDaoException, y funciones globales, y para admitir los tipos de excepción:

Funciones de excepción de DAO

Nombre Descripción
AfxThrowDAOException Produce una CDaoException desde su propio código.
AfxThrowDBException Produce una CDBException desde su propio código.

MFC proporciona la siguiente función de finalización:

Funciones de finalización

Nombre Descripción
AfxAbort Se le llama para finalizar una aplicación cuando se produce un error irrecuperable.

TRY

Configura un bloque TRY.

TRY

Comentarios

Un bloque TRY identifica un bloque de código que podría producir excepciones. Esas excepciones se controlan en los siguientes bloques CATCH y AND_CATCH. Se permite la recursividad: las excepciones se pueden pasar a un bloque TRY externo, ya sea al omitirlas o al usar la macro THROW_LAST. Finalice el bloque TRY con una macro END_CATCH o END_CATCH_ALL.

Para más información, consulte el artículo Excepciones.

Ejemplo

Consulte el ejemplo de CATCH.

Requisitos

Encabezado: afx.h

CATCH

Define un bloque de código que detecta el primer tipo de excepción producido en el bloque TRY anterior.

CATCH(exception_class, exception_object_pointer_name)

Parámetros

exception_class
Especifica el tipo de excepción en busca del cual se realizará una prueba. Para obtener una lista de clases de excepción estándar, consulte la clase CException.

exception_object_pointer_name
Especifica un nombre para el puntero de objeto de excepción que creará la macro. Puede usar el nombre del puntero para tener acceso al objeto de excepción dentro del bloque CATCH. Usted declara esta variable.

Comentarios

El código de procesamiento de excepciones puede interrogar el objeto de excepción, si corresponde, para obtener más información sobre la causa específica de la excepción. Invoque la macro THROW_LAST para desplazar el procesamiento al siguiente marco de excepción externa. Finalice el bloque TRY con una macro de END_CATCH.

Si exception_class es la clase CException, entonces se detectarán todos los tipos de excepción. Puede usar la función miembro CObject::IsKindOf para determinar qué excepción específica se produjo. Una mejor manera de detectar varios tipos de excepciones es usar instrucciones AND_CATCH secuenciales, cada una con un tipo de excepción diferente.

La macro crea el puntero del objeto de excepción. Usted no necesita declararlo.

Nota:

El bloque CATCH se define como un ámbito de C++ delineado por llaves. Si declara variables en este ámbito, solo se puede acceder a ellas dentro de ese ámbito. Esto también se aplica a exception_object_pointer_name.

Para obtener más información sobre las excepciones y la macro CATCH, consulte el artículo Excepciones.

Ejemplo

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 un bloque de código que detecta todos los tipo de excepción producidos en el bloque TRY anterior.

CATCH_ALL(exception_object_pointer_name)

Parámetros

exception_object_pointer_name
Especifica un nombre para el puntero de objeto de excepción que creará la macro. Puede usar el nombre del puntero para acceder al objeto de excepción dentro del bloque CATCH_ALL. Usted declara esta variable.

Comentarios

El código de procesamiento de excepciones puede interrogar el objeto de excepción, si corresponde, para obtener más información sobre la causa específica de la excepción. Invoque la macro THROW_LAST para desplazar el procesamiento al siguiente marco de excepción externa. Si usa CATCH_ALL, finalice el bloque TRY con una macro END_CATCH_ALL.

Nota:

El bloque CATCH se define como un ámbito de C++ delineado por llaves. Si declara variables en este ámbito, solo se puede acceder a ellas dentro de ese ámbito.

Para obtener más información sobre las excepciones, consulte el artículo Excepciones.

Ejemplo

Consulte el ejemplo de CFile::Abort.

Requisitos

Encabezado afx.h

AND_CATCH

Designa un bloque de código para detectar todos los otros tipos de excepciones adicionales producidos en un bloque TRY anterior.

AND_CATCH(exception_class, exception_object_pointer_name)

Parámetros

exception_class
Especifica el tipo de excepción en busca del cual se realizará una prueba. Para obtener una lista de clases de excepción estándar, consulte la clase CException.

exception_object_pointer_name
El nombre para el puntero de objeto de excepción que creará la macro. Puede usar el nombre del puntero para acceder al objeto de excepción dentro del bloque AND_CATCH. Usted declara esta variable.

Comentarios

Use la macro CATCH para detectar un tipo de excepción y, a continuación, la macro AND_CATCH para detectar cada tipo subsiguiente. Finalice el bloque TRY con una macro de END_CATCH.

El código de procesamiento de excepciones puede interrogar el objeto de excepción, si corresponde, para obtener más información sobre la causa específica de la excepción. Llame a la macro THROW_LAST dentro del bloque AND_CATCH para desplazar el procesamiento al siguiente marco de excepción externa. AND_CATCH marca el final del bloque CATCH o AND_CATCH anterior.

Nota:

El bloque CATCH se define como un ámbito de C++ (delineado por llaves). Si declara variables en este ámbito, recuerde que solo se puede acceder a ellas dentro de ese ámbito. Esto también se aplica a variable exception_object_pointer_name.

Ejemplo

Consulte el ejemplo de CATCH.

Requisitos

Encabezado afx.h

AND_CATCH_ALL

Designa un bloque de código para detectar todos los otros tipos de excepciones adicionales producidos en un bloque TRY anterior.

AND_CATCH_ALL(exception_object_pointer_name)

Parámetros

exception_object_pointer_name
El nombre para el puntero de objeto de excepción que creará la macro. Puede usar el nombre del puntero para acceder al objeto de excepción dentro del bloque AND_CATCH_ALL. Usted declara esta variable.

Comentarios

Use la macro CATCH para detectar un tipo de excepción y, a continuación, la macro AND_CATCH_ALL para detectar todos los demás tipos subsiguientes. Si usa AND_CATCH_ALL, finalice el bloque TRY con una macro END_CATCH_ALL.

El código de procesamiento de excepciones puede interrogar el objeto de excepción, si corresponde, para obtener más información sobre la causa específica de la excepción. Llame a la macro THROW_LAST dentro del bloque AND_CATCH_ALL para desplazar el procesamiento al siguiente marco de excepción externa. AND_CATCH_ALL marca el final del bloque CATCH o AND_CATCH_ALL anterior.

Nota:

El bloque AND_CATCH_ALL se define como un ámbito de C++ (delineado por llaves). Si declara variables en este ámbito, recuerde que solo se puede acceder a ellas dentro de ese ámbito.

Requisitos

Encabezado afx.h

END_CATCH

Marca el final del último bloque CATCH o AND_CATCH.

END_CATCH

Comentarios

Para obtener más información sobre la macro END_CATCH, consulte el artículo Excepciones.

Requisitos

Encabezado afx.h

END_CATCH_ALL

Marca el final del último bloque CATCH_ALL88 o AND_CATCH_ALL.

END_CATCH_ALL

Requisitos

Encabezado afx.h

THROW (MFC)

Produce la excepción especificada.

THROW(exception_object_pointer)

Parámetros

exception_object_pointer
Apunta a un objeto de excepción derivado de CException.

Comentarios

THROW interrumpe la ejecución del programa y pasa el control al bloque CATCH asociado en su programa. Si no ha proporcionado el bloque CATCH, el control se pasa entonces a un módulo de la biblioteca MFC (Microsoft Foundation Class) que imprime un mensaje de error y sale del programa.

Para más información, consulte el artículo Excepciones.

Requisitos

Encabezado afx.h

THROW_LAST

Produce la excepción de nuevo y la envía al siguiente bloque CATCH externo.

THROW_LAST()

Comentarios

Esta macro permite producir una excepción creada localmente. Si intenta producir una excepción que acaba de detectar, normalmente saldrá del ámbito y se eliminará. Con THROW_LAST, la excepción se pasa correctamente al siguiente controlador CATCH.

Para más información, consulte el artículo Excepciones.

Ejemplo

Consulte el ejemplo de CFile::Abort.

Requisitos

Encabezado afx.h

AfxThrowArchiveException

Produce una excepción de almacenamiento de archivo.

void  AfxThrowArchiveException(int cause, LPCTSTR lpszArchiveName);

Parámetros

cause
Especifica un entero que indica el motivo de la excepción. Para conocer una lista de los valores posibles, consulte CArchiveException::m_cause.

lpszArchiveName
Apunta a una cadena que contiene el nombre del objeto CArchive que provocó la excepción (si está disponible).

Requisitos

Encabezado afx.h

AfxThrowFileException

Produce una excepción de archivo.

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

Parámetros

cause
Especifica un entero que indica el motivo de la excepción. Para conocer una lista de los valores posibles, consulte CFileException::m_cause.

lOsError
Contiene el número de error del sistema operativo (si está disponible) que indica el motivo de la excepción. Consulte el manual de su sistema operativo para obtener una lista de códigos de error.

lpszFileName
Apunta a una cadena que contiene el nombre del archivo que provocó la excepción (si está disponible).

Comentarios

Usted es responsable de determinar la causa con base en el código de error del sistema operativo.

Requisitos

Encabezado afx.h

AfxThrowInvalidArgException

Produce una excepción de argumento no válida.

Sintaxis

void AfxThrowInvalidArgException( );

Comentarios

Se llama a esta función cuando se usan argumentos no válidos.

Requisitos

Encabezado: afx.h

AfxThrowMemoryException

Produce una excepción de memoria.

void AfxThrowMemoryException();

Comentarios

Llame a esta función si se produce un error en las llamadas a asignadores de memoria del sistema subyacentes (como malloc y la función GlobalAlloc de Windows). No es necesario llamarla para new porque new producirá automáticamente una excepción de memoria si se produce un error en la asignación de memoria.

Requisitos

Encabezado afx.h

AfxThrowNotSupportedException

Representa una excepción que es el resultado de una solicitud de una característica no admisible.

void AfxThrowNotSupportedException();

Requisitos

Encabezado afx.h

AfxThrowResourceException

Produce una excepción de recurso.

void  AfxThrowResourceException();

Comentarios

Normalmente, se llama a esta función cuando no se puede cargar un recurso de Windows.

Requisitos

Encabezado afx.h

AfxThrowUserException

Produce una excepción para detener una operación del usuario final.

void AfxThrowUserException();

Comentarios

Por lo general, se llama a esta función inmediatamente después de que AfxMessageBox ha informado un error al usuario.

Requisitos

Encabezado afx.h

AfxThrowOleDispatchException

Use esta función para producir una excepción dentro de una función de automatización de OLE.

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

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

Parámetros

wCode
Un código de error específico de la aplicación.

lpszDescription
Descripción verbal del error.

nDescriptionID
Id. de recurso para la descripción verbal del error.

nHelpID
Un contexto de ayuda para el archivo de ayuda de su aplicación (. HLP).

Comentarios

La aplicación controladora puede mostrar la información proporcionada a esta función (Microsoft Visual Basic u otra aplicación cliente de automatización de OLE).

Ejemplo

// 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

Encabezado afx.h

AfxThrowOleException

Crea un objeto de tipo COleException y produce una excepción.

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

Parámetros

sc
Un código de estado de OLE que indica el motivo de la excepción.

Hr
El manipulador de un código de resultado que indica el motivo de la excepción.

Comentarios

La versión que toma un HRESULT como argumento convierte ese código de resultado en el SCODE correspondiente. Para obtener más información sobre HRESULT y SCODE, consulte Estructura de códigos de error de COM en Windows SDK.

Requisitos

Encabezado afxdao.h

AfxThrowDaoException

Llame a esta función para producir una excepción del tipo CDaoException desde su propio código.

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

Parámetros

nAfxDaoError
Un valor entero que representa un código de error extendido de DAO, el cual puede ser uno de los valores enumerados en CDaoException::m_nAfxDaoError.

scode
Un código de error de OLE de DAO, de tipo SCODE. Para obtener información, consulte CDaoException::m_scode.

Comentarios

El marco también llama a AfxThrowDaoException. En la llamada, puede pasar uno de los parámetros o ambos. Por ejemplo, si desea generar uno de los errores definidos en CDaoException::nAfxDaoError, pero no le importa el parámetro scode, pase un código válido en el parámetro nAfxDaoError y acepte el valor predeterminado para scode.

Para obtener información sobre las excepciones relacionadas con las clases DAO de MFC, vea la clase CDaoException en este libro y el artículo Excepciones: Excepciones de base de datos.

Requisitos

Encabezado: afxdb.h

AfxThrowDBException

Llame a esta función para producir una excepción del tipo CDBException desde su propio código.

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

Parámetros

nRetCode
Un valor de tipo RETCODE, que define el tipo de error que provocó la excepción.

pdb
Un puntero al objeto CDatabase que representa la conexión del origen de datos con la que está asociada la excepción.

hstmt
Un manipulador HSTMT de ODBC que especifica el manipulador de instrucción con el que está asociada la excepción.

Comentarios

El marco llama a AfxThrowDBException cuando recibe un RETCODE de ODBC de una llamada a una función de la API de ODBC e interpreta el RETCODE como una condición excepcional en lugar de un error esperado. Por ejemplo, una operación de acceso a datos podría producir un error debido a un error de lectura de disco.

Para obtener información sobre los valores RETCODE definidos por ODBC, consulte el capítulo 8, "Recuperación del estado y la información de errores", en Windows SDK. Para obtener información sobre las extensiones de MFC de estos códigos, consulte la clase CDBException.

Requisitos

Encabezado afx.h

AfxAbort

La función de finalización predeterminada proporcionada por MFC.

void  AfxAbort();

Comentarios

Las funciones miembro de MFC llaman a AfxAbort internamente cuando se produce un error irrecuperable, como una excepción no detectada que no se puede controlar. Puede llamar a AfxAbort en el caso poco frecuente en el que encuentre un error catastrófico del que no se puede recuperar.

Ejemplo

Consulte el ejemplo de CATCH.

Requisitos

Encabezado afx.h

Consulte también

Macros y globales
CException (clase)
CInvalidArgException (clase)