Cómo determinar si una excepción es de un tipo particular

82

Tengo un código de captura de prueba:

try 
{
    ...
}
catch(Exception ex) 
{
    ModelState.AddModelError(
        "duplicateInvoiceNumberOrganisation", "The combination of organisation and invoice number must be unique");
}

Para este fragmento de código, estoy tratando de insertar un registro en una base de datos: el dba lo ha configurado para que la base de datos busque duplicados y devuelva un error si hay duplicados. Actualmente, como puede ver, estoy agregando el mismo error al modelo sin importar qué error haya ocurrido. Quiero que se cambie, por lo que este error solo se agrega al modelo si fue causado por el error duplicado configurado por el dba.

A continuación se muestra el error que quiero detectar. Tenga en cuenta que está en la excepción interna. ¿Alguien puede decirme cómo atrapar específicamente este?

ingrese la descripción de la imagen aquí

AnonyMouse
fuente
1
Vea la respuesta de Davide. En general, atrapar Exceptionno es una buena práctica. Debe ser lo más específico posible y dejar que todo lo que no pueda manejar llegue al usuario / marco.
Ryan
1
Consulte esta respuesta: stackoverflow.com/questions/3967140/…
Rob Packwood

Respuestas:

141

antes de su captura actual agregue lo siguiente:

catch(DbUpdateException ex)
{
  if(ex.InnerException is UpdateException)
  {
    // do what you want with ex.InnerException...
  }
}

Desde C # 6, puede hacer lo siguiente:

catch(DbUpdateException ex) when (ex.InnerException is UpdateException)
{
    // do what you want with ex.InnerException...
}
Davide Piras
fuente
3
¿Hay una trampa "cuando no" sintaxis?
conterio
4
@conteriocatch(DbUpdateException ex) when (!(ex.InnerException is UpdateException))
Tom
16

Reemplace System.Threading.ThreadAbortExceptioncon su excepción.

try
{
    //assume ThreadAbortException occurs here
}
catch (Exception ex)
{
    if (ex.GetType().IsAssignableFrom(typeof(System.Threading.ThreadAbortException)))
    {
         //what you want to do when ThreadAbortException occurs         
    }
    else
    {
         //do when other exceptions occur
    }
}
Nishantha
fuente
3

Para obtener el nombre de la excepción, puede usar

    catch (Exception exc){
       if (exc.GetType().FullName == "Your_Exception") 
       {
          // The same can be user for InnerExceptions
          // exc.InnerException.GetType().FullName
       }
   }
Uday Desiraju
fuente
2
Comparar tipo de excepción por cadena es peligroso. ¡Un desafortunado error de ortografía hará que el manejo de excepciones sea una pesadilla!
Tejas Pendse
Convenido. Compare el tipo con un tipo. exc.GetType () == typeof (YourException)
Lee Oades
2

No hay suficiente representante para comentar. En respuesta a la pregunta de @conterio (en la respuesta de @Davide Piras):

¿Hay una trampa de sintaxis "cuando no"?

Ahi esta.

catch (Exception e) when (!(e is ArgumentException)) { }
Jason
fuente
-3

Puede echar un vistazo a la clase SQLException y verificar el contenido del mensaje de la excepción si contiene lo que ahora ve en su excepción interna. Algo como esto:

try
{
    //your code here
}
catch (SQLException ex)
{
    if (ex.Message.Contains("Cannot insert duplicate key in obj...."))
    {
        //your code here
    }
}
Ann BG
fuente
1
Dudo que SqlException se lance directamente, pero solo como una excepción interna. Además, probablemente sería mejor verificar el número de error en lugar de compararlo con el texto del mensaje.
John Saunders
Sí, también puedes comprobar el número de error. Gracias por el comentario.
Ann BG
¿Cómo se compara con el número de error? Ni siquiera estoy seguro de cuál es su número, ya que es un error realmente específico.
AnonyMouse