2010-04-20 11 views
8

Nasz kod znajduje ogólny wyjątek wszędzie.Jak zmienić zastosowanie ogólnego wyjątku?

Zwykle zapisuje błąd w tabeli dziennika w bazie danych i pokazuje komunikat do użytkownika, informujący, że operacja nie powiodła się. Jeśli istnieje interakcja z bazą danych, transakcja jest wycofywana.

Wprowadziłem warstwę logiki biznesowej i warstwę dostępu do danych, aby rozwikłać niektóre elementy logiki. W warstwie dostępu do danych wybrałem, aby niczego nie łapać, a także zgłaszam argumenty ArgumentNullExceptions i ArgumentOutOfRangeExceptions, dzięki czemu komunikat przekazywany do stosu nie pochodzi prosto z bazy danych.

W warstwie logiki biznesowej wstawiłem próbę catch. W haku wycofuję transakcję, wykonuję rejestrowanie i ponowne zgłaszanie.

W warstwie prezentacji znajduje się kolejna próba przechwytywania, która wyświetla komunikat MessageBox.

Teraz myślę o przechwytywaniu wyjątku DataException i ArgumentException zamiast wyjątku, gdy wiem, że kod tylko uzyskuje dostęp do bazy danych.

Gdzie kod uzyskuje dostęp do usługi sieciowej, wtedy pomyślałem, że utworzę własny "WebServiceException", który zostanie utworzony w warstwie dostępu do danych za każdym razem, gdy zostanie zgłoszony wyjątek HttpException, WebException lub SoapException.

Więc teraz, ogólnie rzecz biorąc, złapię 2 lub 3 wyjątki, w których obecnie łapię tylko ogólny wyjątek, i wydaje mi się, że wydaje mi się to w porządku. Czy ktoś ponownie zawija wyjątki, aby przenieść wiadomość do warstwy prezentacji?

Myślę, że prawdopodobnie powinienem dodać próbę catch do Main(), która przechwytuje wyjątek, próbuje go zarejestrować, wyświetla komunikat "Aplikacja napotkała błąd" i kończy działanie aplikacji. Moje pytanie brzmi, czy ktoś widzi jakieś dziury w moim planie? Czy są jakieś oczywiste wyjątki, które powinienem złapać lub zrobić, że te prawie pokrywają to (inne niż dostęp do pliku - myślę, że jest tylko jedno miejsce, w którym zapisujemy do pliku konfiguracyjnego).

Odpowiedz

2

Użyłbym try/finally (lub instrukcji using, która jest odpowiednikiem) do wycofywania, zamiast robić to w bloku catch. W szczególności, jeśli przechwytywane są tylko określone wyjątki, nadal będzie potrzebne wycofanie bazy danych, jeśli zostanie zgłoszony nieoczekiwany typ wyjątku.

Z nielicznymi wyjątkami rzadko używam zaczep wszędzie z wyjątkiem:

  • Na fizycznej granicy tier używam try/catch z dziennika/rzucać w bloku catch tak że wyjątki mogą być zapisywane na serwerze. Dzięki nowszym technologiom, takim jak wyjątki WCF, można rejestrować bez próby/catch (np. Przy użyciu WCF DispatchBehavior).

  • W module obsługi najwyższego poziomu w warstwie prezentacji.

W warstwie biznesowej i danych będzie wiele prób/ostatecznie (np. Za pomocą instrukcji), ale prawie nigdy nie będzie haczyka.

+0

Doskonały punkt na temat końcowego lub użycia wyciągu. Już to robię, gdy transakcja jest w DAL, ale niektóre z moich transakcji nadal znajdują się w BLL, więc myślę, że będę musiał ujawnić metodę MyDatabase.Dispose(), lub zawinąć moją SqlCeTransaction dla "używania" oświadczenia – Colin

+0

Nie wiesz, co masz na myśli przez fizyczną granicę. Czy nie ma granicy przy każdym wywołaniu metody od BLL do DAL? W takim przypadku każde wywołanie w BLL powinno mieć log try/catch log/throw pattern. Ale jeśli będzie to oznaczać fizyczną granicę między aplikacją a bazą danych, aplikacją i usługą sieciową lub aplikacją i systemem plików, to przeniesie moje logowanie do DAL, a nie do BLL. Ale mówisz, że prawie nie ma żadnych pułapek w DAL lub BLL, i oczywiście właśnie utkwiłem, że połowy powinny siedzieć w klasie "MyDatabase", gdzie wszystkie aktualizacje wstawiają się i kasują. To brzmi znacznie lepiej. – Colin

2

Wygląda na to, że wprowadzasz dobre poprawki do swojej aplikacji. Generalnie otwieram najbardziej zewnętrzną warstwę aplikacji w bloku try/catch Exception, tak aby nieoczekiwane wyjątki (na przykład w środowisku wykonawczym) mogły pozwolić na to, że aplikacja wyjdzie z łatwością.

Jedno pytanie dla ciebie jest, jeśli ma to sens, aby przekazać do logiki biznesowej nadzorem wycofywania danych. Wydaje się, że jest to lepiej uwięzione w warstwie dostępu do danych. Następnie można rzucić wyjątek z wyboru z warstwy danych, zamiast otwierać tę warstwę, aby rzucić jakiś stary wyjątek, ponieważ co stanie się z warstwą logiki biznesowej, jeśli warstwa danych wyrzuci coś, czego się nie spodziewa?

A co, jeśli później wyodrębnisz warstwę dostępu do danych i zastąpisz ją czymś innym? Przynajmniej musisz usunąć całą logikę wycofywania z warstwy logiki biznesowej.

+0

Dziękuję Chris. Rozważałem ten dylemat. W logice biznesowej istnieją metody łączące połączenia dostępu do danych, które prawdopodobnie powinny znajdować się całkowicie w warstwie dostępu do danych. Z drugiej strony istnieją pewne metody, które łączą transmisje danych, które mają dla mnie sens w logice biznesowej. Aby obejść to, nazywam MyDatabase.BeginTransaction() w DAL i MyDatabase.RollbackTransaction(). Jestem pewien, że istnieją lepsze sposoby radzenia sobie z transakcjami "Biznesowymi", ale przynajmniej BLL nie jest zależny od SqlCeTransaction ..... – Colin

Powiązane problemy