viernes, 18 de julio de 2014

Excepciones en C# - Parte 4: Propiedades de la Clase Base System.Exception

Tabla de Contenido

0. Introducción
1. Propiedades de la Clase System.Exception
2. Propiedad Data
3. Propiedad HelpLink
4. Propiedad HResult
5. Propiedad InnerException
6. Propiedad Message
7. Propiedad Source
8. Propiedad StackTrace
9. Propiedad TargetSite
10. Artefactos
11 Conclusiones
12. Glosario
13. Literatura & Enlaces

0. Introducción

Esta cuarta parte de Excepciones en C# la dedicaremos al estudio y comprensión de las propiedades de la clase System.Exception. Aprenderemos acerca de su utilidad práctica en la creación, lanzamiento y captura de excepciones, a través de ejemplos sencillos. En concreto estudiaremos las propiedades: Data, HelpLink, HResult, InnerException, Message, Source, StackTrace, y TargetSite.

1. Propiedades de la Clase System.Exception

A continuación describiré y ejemplificaré cada una de las propiedades de la clase Exception [2]. En la Figura 0 se muestra el listado completo de estas propiedades.
Lista de excepciones de la clase System.Exception
Figura 0. Lista de excepciones de la clase System.Exception.

2. Propiedad Data

La propiedad Data (System.Exception) obtiene una colección de pares llave/valor para permitir al usuario de una excepción incluir información adicional acerca del evento de generación de excepción [3].

Firma de esta propiedad:

public virtual IDictionary Data { get; }

Descripción puntual:
  • Valores de la propiedad:
    • Tipo: System.Collections.IDictionary [4]
    • Descripción: Cualquiera clase que implementa esta interfaz basada en un diccionario de pares llave/valor. Esta colección al crearse una instancia de un tipo de excepción, estará vacía.

2.1 Recomendaciones de uso

2.1.1 Seguridad

En [2] advierten que la información almacenada en la colección de pares llave/valor retornada por esta propiedad no es segura. Y lo argumenta de la siguiente manera (en inglés):
«...If your application calls a nested series of routines, and each routine contains exception handlers, the resulting call stack contains a hierarchy of those exception handlers. If a lower-level routine throws an exception, any upper-level exception handler in the call stack hierarchy can read and/or modify the key/value pairs stores in the collection by any other exception handler...»

2.1.2 Conflictos de llaves

Los conflictos de llave se originan cuando diferentes manejadores de excepciones recurren a una misma llave para acceder a un par llave/valor. Para evitar esto, se recomienda usar una convención para el nombramiento de llaves. Por ejemplo:
  • Nombre_Aplicación.Nombre_Metodo.Identificador

1.2 Ejemplo de uso

Procedamos a comprender el siguiente ejemplo de uso de esta propiedad para agregar información útil sobre el evento de generación de una excepción.

Líneas de código a destacar:
  • Línea 17: Invocación del método GenerarExcepcion.
  • Líneas 40-54
    • Línea 42: Creación de una instancia de la clase Systme.Exception [2].
    • Líneas 44-46: Creación de tres variables: DataTime, string, y int.
    • Líneas 49-51: Asignación de los valores de las tres variables anteriores a llaves de la propiedad Data de la instancia e.
    • Línea 53: Lanzamiento de la excepción e.
  • Líneas 19-36: tratamiento de la excepción Exception:
    • Línea 25: Valida que la propiedad Data de la excepción capturada tenga elementos.
    • Líneas 28-34: Ciclo foreach para iterar a través de las llaves de la propiedad Data.
Compilación:

  1. csc /target:exe UsoData.cs

Ejecución assembly:

  1. .\UsoData.exe


> Prueba de ejecución (local):
Ejecución assembly UsoData.exe
Figura 1. Ejecución assembly UsoData.exe.

3. Propiedad HelpLink

Con la propiedad HelpLink se estable o se obtiene la cadena de caracteres que representa el archivo de ayuda de una determinada excepción [5]. Firma:

public virtual string HelpLink { get; set; }
  • Valores de la propiedad:
    • Tipo: System.String
    • Descripción: cadena caracteres de la ruta del archivo de ayuda, inclusive, una cadena que represente un URL [7] o un URN [8].
[Nota: El ejemplo de uso de esta propiedad en la sección 9 (Propiedad System.TargetSite).]

4. Propiedad HResult

Con la propiedad HResult (System.Exception) se establece o se obtiene un valor numérico que corresponde con código asignado a una excepción específica [6]. Firma:

public int HResult { get; protected set; }
  • Valores de propiedad:
    • Tipo: int
      • Valor entero que representa el código HRESULT.
El código HRESULT es un entero de 32 bits (Int32) que está compuesto por tres partes:
  1. Código de severidad: Indica si el valor retornada es de información, advertencia, o de error.
  2. Código de locación: Área del sistema responsable de la generación del error.
  3. Código de error: Número que identifica el tipo de error generado por la excepción.

4.1 Ejemplo de uso

Demostremos el uso de esta propiedad con este ejemplo, el cual consiste en el diseño de una excepción que asigna un código de error a la hora de generarse una excepción en código cliente.

En las líneas 7-18 creamos una clase de excepción que posee las siguientes características:
  • Línea 9: Código HRESULT representado como una constante entera. La palabra clave unchecked omite la comprobación de desbordamiento sobre las operaciones de aritmética entera.
  • Líneas 12-17: Creación constructor para inicializar el constructor de la clase base Exception, y asignar el valor HRESULT de esta clase al heredado.
En el método Main (líneas 22-46) se genera una excepción de división entre cero de forma intencionada. Dentro del bloque catch de las líneas 34-40 se lanza una nueva excepción, pero esta vez de tipo DivisionPorCeroException (recomiendo la lectura de la parte 3 de excepciones: Diseño de Excepciones Personalizada). Esta última excepción es atrapada por el bloque catch que se haya entre las líneas 42-45.

Compilación:

  1. csc /target:exe UsoHResult.cs

Ejecución assembly:

  1. .\UsoHResult.exe


> Prueba de ejecución (local):
Ejecución assembly UsoHResult.exe
Figura 2. Ejecución assembly UsoHResult.exe.

5. Propiedad System.Exception.InnerExcepcion

Obtiene la instancia de tipo Exception, la cual generó la excepción actual. Firma [11]:

public Exception InnerException { get; }

Descripción puntual:
  • Valores de propiedad:
    • Tipo: System.Exception
    • Descripción: Obtiene la instancia de la excepción que ocasionó la excepción actual.
El uso conceptual de esta propiedad se ve en la siguiente región de código:

try
{
try
{
throw new Exception();
}
catch(Exception innerException)
{
throw new OtraException("Mensaje", innerException)
}
}
catch(Exception e)
{
// Obtiene la excepción generada anteriormente:
Exception innerException = e.InnerException;
}


que lanza una excepción (parte superior), la atrapa, y genera una nueva que es atrapada por el bloque catch exterior y asigna a la variable local innerException la instancia de la excepción anidada que se generó más arriba.



Un ejemplo concreto lo podemos encontrar en el código de ejemplo de la sección 4.1, precisamente en las líneas 27-45.

6. Propiedad System.Exception.Message

La propiedad Message obtiene un mensaje de descripción de la excepción generada. Esta es su firma [11]:

public virtual string Message { get; }

Descripción puntual:
  • Valores de de propiedad:
    • Tipo: System.String
    • Descripción: Mensaje de error con la descripción que generó la excepción.
[Nota: El ejemplo de uso de esta propiedad en la sección 9 (Propiedad System.TargetSite).]

7. Propiedad System.Exception.Source

La propiedad Source establece o obtiene el nombre de la aplicación o la instancia de clase que causó el error de excepción. Firma [12]:

public virtual string Source { get; set; }

Descripción puntual:
  • Valores de propiedad:
    • Tipo: System.String
    • Descripción: El nombre de la aplicación que causó el error. En caso de que no se asigne ningún valor a esta propiedad, la CLR se asigna automáticamente el nombre del assembly desde donde se generó la excepción.
[Nota: El ejemplo de uso de esta propiedad en la sección 9 (Propiedad System.TargetSite).]

8. Propiedad System.Exception.StackTrace

Esta es quizás una de las propiedades más interesantes, debido a que contiene el rastreo de las tramas (sinónimo de secciones o puntos de de llamadas de métodos sucesivos) de la excepción generada.

Firma [13]:

public virtual string StackTrace { get; }

Descripción puntual:
  • Valores de propiedad:
    • Tipo: System.String
    • Descripción: Cadena de caracteres que representa las tramas de la pila de llamada de métodos. La trama contiene el punto exacto donde se generó la excepción. El punto consiste en el método, número de línea y columna.
[Nota: El ejemplo de uso de esta propiedad en la sección 9 (Propiedad System.TargetSite).]

9. Propiedad System.Exception.TargetSite

TargetSite obtiene el nombre del método (instancia de MethodBase [15]) que la lanzó la excepción actual.

Firma [14]:

Descripción puntual:
  • Valores de propiedad:
    • Tipo: System.Reflection.MethodBase
    • Descripción: Instancia MethodBase que representa el método que lanzó la excepción actual.
En el siguiente ejemplo además de ver el uso de la propiedad TargetSite, también se ejemplificará las siguientes propiedades:
  • HelpLink
  • Source, y 
  • StackTrace
En las líneas 6-18 se diseña una excepción personalizada para aquellas casos de adición de registro que sobrepasan el límite de una tabla de manejo de registros. La clase TablaRegistro (líneas 20-47) en el método AgregarRegistro se genera una excepción siempre y cuando se sobrepase el límite de almacenamiento:

registros[elementoActual] = registro;

En el método Main (líneas 51-78) ocurren las siguientes acciones:
  • Líneas 60-68: Bloque try para atrapar cualquier excepción generada indirectamente por el método AgregarRegistro.
  • Líneas 69-77: Cuando se atrapa la excepción generada en el bloque try anterior, se imprime en pantalla los valores de las propiedades Message, TargetSite, HelpLink, Source, y StackTrace.
Compilación:


  1. csc /target:exe UsoTargetSite.cs

Ejecución assembly:


  1. .\UsoTargetSite.exe

> Prueba de ejecución (ideone.com).

> Prueba de ejecución (local):
Ejecución assembly UsoTargetSite.exe
Figura 3. Ejecución assembly UsoTargetSite.exe.

10. Artefactos

Enlaces de descarga de los artefactos producidos durante el desarrollo de este artículo:

11. Conclusiones

Hemos explorado cada una de las propiedades (9) de la clase System.Exception. Su correcto y adecuado uso nos permite diseñar, crear, usar excepciones de forma más eficiente. Para módulos o componentes de librerías que incluyen excepciones personalizadas, el implementar correctamente las propiedades de Exception, facilita el uso de nuestro producto a programadores; ¿cómo?, suministrándole información completa sobre la falla o error que ha generado el uso incorrecto del componente en alguna sección de código.  En la última parte de esta serie de excepciones, crearemos ejemplos de las clases de excepciones más comunes en la biblioteca base de clases.

Glosario

  • Captura
  • Excepción
  • Excepción personalizada
  • Lanzamiento
  • Módulo
  • Propiedad

Literatura & Enlaces

[1]: C# 5.0 in a Nutshell by Joseph Albahari and Ben Albahari. Copyright 2012 Joseph Albahari and Ben Albahari, 978-1-449-32010-2.
[2]: Exception Class (System) - http://msdn.microsoft.com/en-us/library/system.exception(v=vs.110).aspx
[3]: Exception.Data Property (System) - http://msdn.microsoft.com/en-us/library/system.exception.data%28v=vs.110%29.aspx
[4]: IDictionary Interface (System.Collections) - http://msdn.microsoft.com/en-us/library/system.collections.idictionary(v=vs.110).aspx
[5]: Exception.HelpLink Property (System) - http://msdn.microsoft.com/en-us/library/system.exception.helplink%28v=vs.110%29.aspx
[6]: Exception.HResult Property (System) - http://msdn.microsoft.com/en-us/library/system.exception.hresult%28v=vs.110%29.aspx
[7]: Uniform resource locator - Wikipedia, the free encyclopedia - https://en.wikipedia.org/wiki/Uniform_Resource_Locator
[8]: Uniform resource name - Wikipedia, the free encyclopedia - https://en.wikipedia.org/wiki/Uniform_Resource_Name
[9]: Excepciones en C#: Diseño de Excepciones Personalizadas | OrtizOL - Experiencias Construcción Software (xCSw) - http://ortizol.blogspot.com/2014/07/excepciones-en-csharp-parte-3-diseno-de-excepciones-personalizadas.html
[10]: Exception.InnerException Property (System) - http://msdn.microsoft.com/en-us/library/system.exception.innerexception%28v=vs.110%29.aspx
[11]: Exception.Message Property (System) - http://msdn.microsoft.com/en-us/library/system.exception.message(v=vs.110).aspx
[12]: Exception.Source Property (System) - http://msdn.microsoft.com/en-us/library/system.exception.source(v=vs.110).aspx
[13]: Exception.StackTrace Property (System) - http://msdn.microsoft.com/en-us/library/system.exception.stacktrace%28v=vs.110%29.aspx
[14]: Exception.TargetSite Property (System) - http://msdn.microsoft.com/en-us/library/system.exception.targetsite(v=vs.110).aspx
[15]: MethodBase Class (System.Reflection) - http://msdn.microsoft.com/en-us/library/system.reflection.methodbase(v=vs.110).aspx


J

No hay comentarios:

Publicar un comentario

Envíe sus comentarios, dudas, sugerencias, críticas. Gracias.