He tomado el consejo que he visto en otras preguntas respondidas sobre cuándo lanzar excepciones, pero ahora mis API tienen un ruido nuevo. En lugar de llamar a métodos envueltos en bloques try/catch (molestas excepciones), tengo parámetros de argumentos sin salida con una colección de errores que pueden haber ocurrido durante el procesamiento. Entiendo por qué envolver todo en un try/catch es una mala forma de controlar el flujo de una aplicación, pero rara vez veo código en cualquier lugar que refleje esta idea.¿Cómo se ve el código cuando no usa excepciones para controlar el flujo?
Es por eso que todo esto me parece tan extraño. Es una práctica que supuestamente es la forma correcta de codificar, pero no la veo en ningún lado. Además de eso, no entiendo muy bien cómo relacionarme con el código del cliente cuando ha ocurrido un comportamiento "malo".
Aquí hay un fragmento de código con el que estoy trabajando y que trata de guardar imágenes que cargan los usuarios de una aplicación web. No te preocupes por los detalles (es feo), solo mira cómo agregué estos parámetros de salida a todo para obtener mensajes de error.
public void Save(UserAccount account, UserSubmittedFile file, out IList<ErrorMessage> errors)
{
PictureData pictureData = _loader.GetPictureData(file, out errors);
if(errors.Any())
{
return;
}
pictureData.For(account);
_repo.Save(pictureData);
}
¿Es esta la idea correcta? Puedo razonablemente esperar que un archivo enviado por el usuario sea inválido de alguna manera, así que no debería lanzar una excepción, sin embargo, me gustaría saber qué está mal con el archivo, así que produzco mensajes de error. Del mismo modo, cualquier cliente que ahora consume este método de guardado también querrá saber qué fue lo que falló con la operación general de guardado de imágenes.
Tenía otras ideas sobre devolver algún objeto de estado que contuviera un resultado y mensajes de error adicionales, pero eso se siente raro. Sé que tener parámetros en todas partes va a ser difícil de mantener/refactorizar/etc.
¡Me gustaría algo de orientación sobre esto!
EDIT: Creo que el fragmento de archivo enviado por el usuario puede llevar a las personas a pensar en excepciones generadas al cargar imágenes no válidas y otros errores "difíciles". Creo que este fragmento de código es una mejor ilustración de dónde creo que se está desalentando la idea de lanzar una excepción.
Con esto estoy guardando una nueva cuenta de usuario. Hago una validación de estado en la cuenta de usuario y luego presiono la tienda persistente para averiguar si se tomó el nombre de usuario.
public UserAccount Create(UserAccount account, out IList<ErrorMessage> errors)
{
errors = _modelValidator.Validate(account);
if (errors.Any())
{
return null;
}
if (_userRepo.UsernameExists(account.Username))
{
errors.Add(new ErrorMessage("Username has already been registered."));
return null;
}
account = _userRepo.CreateUserAccount(account);
return account;
}
¿Debo arrojar algún tipo de excepción de validación? ¿O debería devolver los mensajes de error?
También aprendí cosas importantes con respecto a arrojar/atrapar excepciones en SO. Pero creo que debes haber malinterpretado algunas (o la mayoría) de las cosas que leíste aquí, para llegar a una solución como esa. –
¡Ah, entonces debes saber cuál es la solución! Cuidado de compartir? –
Mi punto es que las respuestas que estás buscando están aquí y solo necesitas volver a leerlas con un estado de ánimo diferente. –