2008-10-13 15 views
15

Jakie są wytyczne dotyczące tworzenia nowego typu wyjątku zamiast korzystania z jednego z wbudowanych wyjątków w .Net?Kiedy używać nowego wyjątku typu:

Problem, który skłonił mnie do myślenia, jest taki. Mam usługę WCF, która jest podstawową usługą wejścia-wyjścia. Jeśli usługa nie może utworzyć wyjścia, ponieważ dane wejściowe są nieprawidłowe, chcę rzucić wyjątek, ale który?

W tej chwili po prostu wyrzucam system. Wyjątek, ale to nie wydaje mi się właściwe, nie wiem dlaczego, po prostu czuje się źle. Jedna rzecz, która mnie trapi, jeśli testuję ją testem jednostkowym i oczekuję wyrzucenia wyjątku systemowego. Wyjątek mógłby równie dobrze zostać wyrzucony przez framework lub inny kod, a nie przez kod, który wyrzuciłem. Test przejdzie następnie, ponieważ otrzymam oczekiwany wyjątek, ale powinien on zakończyć się niepowodzeniem.

Co polecasz?

+0

Myślę, że jest to odpowiednie dla wszystkich języków używających wyjątków. –

Odpowiedz

15

Należy unikać samodzielnego rzucania System.Exception lub System.ApplicationException, ponieważ są one zbyt ogólne.

W przypadku usług WCF istnieją kontrakty awaryjne - ogólny wyjątek, który można powierzyć subskrybentom.

Oznacz interfejs z:

[FaultContract(typeof(LogInFault))] 
void LogIn(string userName, string password, bool auditLogin); 

Następnie, jeśli istnieje wyjątek można rzucić ten konkretny błąd:

throw new FaultException<LogInFault>(new LogInFault(), "message"); 

Użyj [DataContract] serializacji na swojej winy - to pozwala uniknąć konieczności obsłużyć wszystkie wyjątki seryjne, które zwykle wymagają wyjątki.

+1

@ Keith- to jest dobre. Aby było jeszcze lepiej, podaj przykład LoginFault. – RichardOD

7

Zdecydowanie unikaj wyrzucania wyjątku System.Exception pod kątem czegoś innego niż kod wyrzucania.

Jeśli argument metody jest nieprawidłowy, należy podać ArgumentException (lub inny wyprowadzony, bardziej szczegółowy wyjątek). Przed utworzeniem własnego dokumentu zapoznaj się z dokumentacją dotyczącą istniejących wyjątków, ale często może to być przydatne. (Oczywiście można wyprowadzić własny typ wyjątku z ArgumentException - jeśli masz jakiś szczególny typ warunku, który chcesz wskazać z wielu miejsc, utworzenie nowego typu daje więcej informacji niż tylko umieszczenie go w komunikacie o błędzie.)

Obsługa błędów w WCF może być inna niż obsługa błędów w "normalnych" ramach - radzę odnieść się do dokumentacji/książek specyficznych dla WCF.

+0

Podczas korzystania z WCF zwykle trzeba rozróżniać wyjątki, które wynikają z danych wejściowych klienta (nadawcy) z powodu problemów/błędów serwera. ArgumentException jest zbyt ogólny - lepiej użyć FaultContract. – Joe

0

Zawsze twórz nowy typ wyjątku (lub użyj standardowego typu, jeśli Ci odpowiada).

W takim przypadku można obsługiwać wyjątki jako grupę.

2

To nie jest dobry pomysł, aby rzucić wyjątek System.Exception. Największym tego powodem jest wpływ, jaki ma na kod wywołujący. Jak powinny obsługiwać wyjątek? Jeśli kod wywołujący będzie obsługiwał wyjątek, muszą przechwycić każdy wyjątek, co prawdopodobnie nie jest najlepszą rzeczą do zrobienia.

Jeśli okoliczność nie jest objęta jednym ze standardowych wyjątków, powinieneś utworzyć nowy obiekt wyjątku, jeśli wyjątek jest czymś, co kod wywołujący powinien obsługiwać jako specjalny przypadek.

2

Wyjątek System.Exception powinien być używany tylko jako klasa bazowa Wyjątków, nigdy nie powinien być wyrzucany bezpośrednio.

Ramowa oferuje już wiele ważnych klas wyjątków, takich jak ArgumentException, ArgumentNullException, InvalidOperationException, FormatException, OverflowException, etc ...

Mówisz robisz I/O rzeczy, więc dobrym pomysłem jest szukanie przy podobnych operacjach w ramach (takich jak int.Parse) i generują te same wyjątki dla podobnych błędów.

Albo wyprowadź własną klasę wyjątków z istniejącej klasy wyjątków, jeśli żadna z nich nie pasuje do twoich potrzeb.

1

Jakie są wytyczne dla kiedy utworzyć nowy wyjątek wpisz zamiast za pomocą jednego z wbudowanych wyjątków w .NET?

Gdy nie ma odpowiedniej predefiniowanej klasy wyjątków.
.NET FW jest bardzo bogaty, często można znaleźć predefiniowany wyjątek.

Jeżeli usługa jest w stanie utworzyć wyjściowy , ponieważ wejście jest nieważny

ArgumentException Class (System)

wyjątkiem tego, że jest wyrzucana po jednym argumentów dostarczane do metody jest nieprawidłowy.

0

Zgodnie z poprzednimi plakatami nie należy rzucać wyjątku System.Exception. W rzeczywistości, jeśli uruchomisz FxCop na swoim kodzie, oznaczy to jako naruszenie zasad.

Polecam zapoznanie się z rozdziałem 18 aplikacji .NET Framework Programming lub rozdziałem 19 najnowszego CLR za pośrednictwem C# (2. wydanie) w celu uzyskania szczegółowych wskazówek. Richter wykonuje świetną robotę polegającą na korygowaniu błędnych przekonań, które wielu programistów posiada na temat wyjątków.

Obie książki zawierają listę wyjątków zdefiniowanych przez bibliotekę klasy ramowej. Spójrz na listę i poznaj najbardziej szczegółowe wyjątki możliwe do wyrzucenia przez Twój kod. Jeśli możesz odzyskać od wyjątku, zrób to w tym bloku catch. Jeśli potrzebujesz wielu bloków catch, uporządkuj je od najbardziej konkretnego do najmniej szczegółowego. Utwórz niestandardowy wyjątek, jeśli nie możesz znaleźć go na istniejącej liście, która pasuje do sytuacji.

2

Jeśli rzucisz System.Exception, to wywołujący musi złapać wyjątek System.Exception. Obie strony tego są nie-nie, ponieważ pozostawia nam mówienie użytkownikowi "to nie działa", a nie coś bardziej użytecznego.

Wyjątek ArgumentException jest przydatny, jeśli wywołujący przekazał niepoprawny argument. Jeśli twoja funkcja ma parametr int, który musi być liczbą parzystą, to możesz rzucić i ArgumentException informując dzwoniącego, który parametr jest nieprawidłowy i dlaczego. Jeśli jednak wszystkie argumenty są poprawne, ale nadal występuje problem, prawdopodobnie będziesz potrzebować niestandardowego wyjątku. W ten sposób dzwoniący może powiedzieć użytkownikowi, co poszło nie tak.

Test dla mnie jest naprawdę po stronie wzywającej. Gdybym miał tuzin połowów, które wszystkie zrobiłyby to samo, wtedy potrzebowałem tylko jednego wyjątku. Jednakże, gdybym miał jeden haczyk i miałbym oświadczenie mówiące użytkownikowi, że jedna z trzech rzeczy poszła nie tak, to naprawdę potrzebowałem trzech unikalnych wyjątków.

Powiązane problemy