Después de buscar en varios repositorios y sitios webs de internet finalmente hemos descubierto la resolución que te mostraremos más adelante.
Solución:
Necesita c# 6/visual studio 2015 para hacer esto usando un predicado:
catch (ArgumentException e) when (e.ParamName == “…”)
Documentación oficial de C# Try/Catch
Odio tener que decirte esto, pero no puedes detectar una excepción interna.
lo que puedes hacer es inspeccionar una.
Le sugiero que detecte su excepción de alto nivel (creo que fue LockerException
) e inspeccione el InnerException
propiedad de esa excepción. Compruebe el tipo, y si no es un SqlException
comprobar el InnerException
de esa excepción. Recorre cada uno hasta que encuentres un SqlException
escriba, luego obtenga los datos que necesita.
Dicho esto, estoy de acuerdo con dasblinkenlight en que debe considerar, si es posible, un refactor pesado de su marco de excepción.
Verificar el código de error de una excepción envuelta no es una buena práctica, porque daña la encapsulación bastante severamente. Imagínese en algún momento reescribir la lógica para leer desde una fuente que no sea SQL, por ejemplo, un servicio web. arrojaría algo más que SQLException
bajo la misma condición, y su código externo no tendría forma de detectarlo.
Debes agregar código a la captura de bloques. SQLException
para comprobar e.Number = 247
en ese momento y allí, y tirar BusinessRuleException
con alguna propiedad que lo diferencie de BusinessRuleException
lanzada en respuesta a no-SQLException
y SQLException
con e.Number != 247
de alguna manera significativa. Por ejemplo, si el número mágico 247
significa que ha encontrado un duplicado (una pura especulación de mi parte en este punto), podría hacer algo como esto:
catch (SQLException e)
var toThrow = new BusinessRuleException(e);
if (e.Number == 247)
toThrow.DuplicateDetected = true;
throw toThrow;
cuando atrapas BusinessRuleException
más tarde, puede comprobar su DuplicateDetected
propiedad y actuar en consecuencia.
EDITAR 1 (en respuesta al comentario de que el código de lectura de base de datos no puede verificar SQLException
)
También puede cambiar su BusinessRuleException
para comprobar SQLException
en su constructor, así:
public BusinessRuleException(Exception inner)
: base(inner)
SetDuplicateDetectedFlag(inner);
public BusinessRuleException(string message, Exception inner)
: base(message, inner)
SetDuplicateDetectedFlag(inner);
private void SetDuplicateDetectedFlag(Exception inner)
var innerSql = inner as SqlException;
DuplicateDetected = innerSql != null && innerSql.Number == 247;
Esto es menos deseable, porque rompe la encapsulación, pero al menos lo hace en un solo lugar. Si necesita examinar otros tipos de excepciones (por ejemplo, porque agregó una fuente de servicio web), puede agregarla a la SetDuplicateDetectedFlag
método, y todo volvería a funcionar.
Comentarios y puntuaciones
Puedes confirmar nuestro quehacer añadiendo un comentario o valorándolo te damos la bienvenida.