Nie wierzę, że lokalne połowy są anty-wzorcem, w rzeczywistości, jeśli dobrze pamiętam, faktycznie są egzekwowane w Javie!
Najważniejsze dla mnie przy wdrażaniu obsługi błędów jest ogólna strategia. Możesz potrzebować filtra, który wychwytuje wszystkie wyjątki na granicy usługi, możesz chcieć je ręcznie przechwycić - oba są w porządku, o ile istnieje ogólna strategia, która będzie zgodna ze standardami kodowania twoich zespołów.
Osobiście lubię wychwytywać błędy wewnątrz funkcji, gdy mogę wykonać jedną z następujących czynności:
- Dodaj informacje kontekstowe (takie jak stan obiektów lub co się działo)
- Obsługuj wyjątek bezpiecznie (na przykład metoda TryX)
- Twój system przekracza granicę usługi i dzwoni do zewnętrznej biblioteki lub interfejsu API
- Chcesz złapać i ponownie rzucić inny typ wyjątku (być może oryginał stanowi wyjątek wewnętrzny)
- Wyjątek został zgłoszony w ramach funkcji o niskiej wartości w tle
Jeśli to nie jeden z tych przypadków, nie dodam lokalnej try / catch. Jeśli tak, w zależności od scenariusza mogę obsłużyć wyjątek (na przykład metodę TryX, która zwraca wartość false) lub powtórzyć, aby wyjątek był obsługiwany przez globalną strategię.
Na przykład:
public bool TryConnectToDatabase()
{
try
{
this.ConnectToDatabase(_databaseType); // this method will throw if it fails to connect
return true;
}
catch(Exception ex)
{
this.Logger.Error(ex, "There was an error connecting to the database, the databaseType was {0}", _databaseType);
return false;
}
}
Lub przykład powtórzenia:
public IDbConnection ConnectToDatabase()
{
try
{
// connect to the database and return the connection, will throw if the connection cannot be made
}
catch(Exception ex)
{
this.Logger.Error(ex, "There was an error connecting to the database, the databaseType was {0}", _databaseType);
throw;
}
}
Następnie wychwytujesz błąd na górze stosu i przekazujesz użytkownikowi przyjazną wiadomość.
Niezależnie od tego, jakie podejście podejmiesz, zawsze warto utworzyć testy jednostkowe dla tych scenariuszy, aby mieć pewność, że funkcjonalność się nie zmieni i nie zakłóci przepływu projektu w późniejszym terminie.
Nie wspomniałeś, w jakim języku pracujesz, ale jesteś programistą .NET i widziałeś to zbyt wiele razy, nie mówiąc już o tym.
NIE PISZ:
catch(Exception ex)
{
throw ex;
}
Posługiwać się:
catch(Exception ex)
{
throw;
}
Ten pierwszy resetuje ślad stosu i sprawia, że złapanie najwyższego poziomu jest całkowicie bezużyteczne!
TLDR
Lokalne łapanie nie jest anty-wzorcem, często może być częścią projektu i może pomóc w dodaniu dodatkowego kontekstu do błędu.