Implementamos la mayoría de nuestras reglas de negocio en la base de datos, utilizando procesos almacenados.¿Cómo manejar las violaciones de restricción db en la interfaz de usuario?
Nunca puedo decidir cómo pasar los errores de violación de restricción de datos de la base de datos a la interfaz de usuario. Las limitaciones de las que hablo están más ligadas a las reglas comerciales que a la integridad de los datos.
Por ejemplo, un error de db como "No se puede insertar una fila de clave duplicada" es lo mismo que la regla de negocios "no se puede tener más de un Foo con el mismo nombre". Pero lo hemos "implementado" en la ubicación con el sentido más común: como una restricción única que arroja una excepción cuando se infringe la regla.
Otras reglas como "Solo se permiten 100 Foos por día" no causan errores, por ejemplo, ya que se manejan con gracia mediante código personalizado como return empty dataset
que el código de la aplicación busca y devuelve al ui capa.
Y ahí radica el problema. Nuestro código de interfaz de usuario se parece a esto (este es el código AJAX.NET servicios web, pero cualquier marco ajax hará):
WebService.AddFoo("foo", onComplete, onError); // ajax call to web service
function onComplete(newFooId) {
if(!newFooId) {
alert('You reached your max number of Foos for the day')
return
}
// update ui as normal here
}
function onError(e) {
if(e.get_message().indexOf('duplicate key')) {
alert('A Foo with that name already exists');
return;
}
// REAL error handling code here
}
(Como nota al margen: Me he dado cuenta que esto es lo que hace stackoverflow al momento de enviar los comentarios con demasiada rapidez: el servidor genera una respuesta HTTP 500
y el ui lo capta)
Como puede ver, estamos manejando infracciones de reglas comerciales en dos lugares, uno de los cuales (es decir, el error de constancia único) se maneja como un caso especial para el código que se supone que maneja errores reales (no infracciones de reglas comerciales), ya que .NET propaga Excepciones hasta el controlador onError()
.
Esto se siente mal. Mis opciones creo que son:
- captura la excepción 'duplicado violación clave' en el nivel de servidor de aplicaciones y convierten a lo que es la interfaz de usuario espera como la "regla de negocio violado" bandera,
- adelantar el error (digamos, con un
"select name from Foo where name = @Name"
) y devolver lo que sea que el servidor de la aplicación espera como la bandera "regla comercial violada" - en el mismo estadio que 2): aprovechar la restricción única incorporada en la capa db y ciegamente
insert into Foo
, atrapando cualquier excepción y convirtiéndola en lo que sea que sea la aplicación que se sirve r espera como la "regla de negocio violó" bandera - ciegamente
insert into Foo
(como 3) y dejar que la excepción se propaga a la interfaz de usuario, además tienen las violaciónes de reglas de negocio de servidores de aplicaciones plantean como bienesExceptions
(en contraposición a 1). De esta forma, TODOS los errores se manejan en el códigoonError()
(o similar) de la capa ui.
Lo que me gusta 2) y 3) es que las violaciónes de reglas de negocio son "arrojados" donde se implementan: en el procedimiento almacenado. Lo que no me gusta de 1) y 3) es que creo que implican controles estúpidos como "if error.IndexOf('duplicate key')"
, al igual que lo que está en la capa ui actualmente.
Editar: me gusta 4), pero la mayoría de la gente dice utilizar Exception
s sólo en excepcionales circunstancias.
Entonces, ¿cómo manejan ustedes las personas que propagan las violaciones de reglas comerciales hasta la interfaz de usuario con elegancia?
Deseo que la persona que votó negativamente por esto y http://stackoverflow.com/questions/581994/-net-coding-standards-and-framework-for-a-web-service/582429#582429 den una razón. Dos respuestas muy diferentes, el mismo resultado, en un minuto. –
El código que eventualmente llama a 'RAISERROR' todavía necesitará realizar una" verificación estúpida "como' CHARINDEX ('duplicate key', @errorMessage)> 0' y encontré esta pregunta porque mi escenario de ejemplo involucra * dos * clave única potencial Violaciones de restricciones y tenía curiosidad de saber si había alguna manera de determinar qué clave se había violado sin buscar los nombres de las claves o los nombres de las columnas relevantes. –