04. januar 2005 - 20:10Der er
18 kommentarer og 2 løsninger
Try catch
Hej,
Jeg har noget ASP.NET kode og jeg har lavet en Database facade som indeholder alt koden vedrørende database kald.
Jeg har valgt at gøre det på denne måde, da det så vil blive nemmere at skifte databasen ud - så skal man kun ændre i facadeklassen. Det kører pt med access, men skal over på MS Sql om ikke så lang tid.
Men mit spørgsmål:
Bør jeg skrive try-catch blokke i facade klassen, eller skal jeg gøre det der hvor facade klassens metoder rent faktisk bliver kaldt?
en mulighed var evt. at fange dine fejl i facade-klassen og kaste en ny generisk exception med indholdet af den originale. Dette har jeg selv gjort med success, da jeg ellers skal vide hvilken slags database jeg har med at gøre når jeg kalder metoderne i facade-klassen. Og hvorfor det? Jo, fordi at der findes SqlConnectionException, OleDbConnectionException, MySqlConnectionException osv. osv.
Funktionen returnerer, som det fremgår, en string. Men hvis jeg compiler ovenstående kode siger den: "Not all paths have a return value" (eller noget i den stil).
Det hvor det kan gå galt er der hvor strTemp tilskrives - hvis ds.Tables ikke indeholder noget får man en fejl under runtime med den gule skærm der melder fejl - dvs applikationen går ned (det ønsker jeg ikke). Så det er dette jeg forsøger at fange. Jeg kunne bare skrive return "etellerandet" udenfor try-catch blokken, men jeg ønsker, at det skal fanges hvis strTemp ikke får nogen værdi.
Som i kan høre er jeg ikke helt inde i koncepterne for exception handling. Hvordan kan man løse ovenstående problem?
jeg har besluttet mig for at catche der hvor jeg kalder metoderne fra klient klasserne. dvs der er INGEN exception handling i facade klassen til databasen.
hvad nu hvis databasen fx ikke eksisterer? den fanger jeg også fra klientklasserne som det er nu - håber ikke det er helt forkert :-)
på ingen måde forkert... bare pas på du ikke ender med at catche f.eks. SqlConnectionException dine klientklasser, da hele ideen med facadeklassen så ryger sig en tur
ok så skal jeg bare lade være med at fange database specifikke exceptions?
det giver god mening det du siger, for jeg kører pt med access men skal over på ms sql og ideen er jo at man kan nøjes med at udskifte facade klassen...
i så fald skal du finde en mindste fællesnævner. Efter at have kigget i dokumentationen ser det ud til at det ikke helt er tilfældet.
OleDbException arver fra ExternalException, da der nok bliver lavet en del COM-kald tilbage til det gamle ADO, mens at SqlClient er skrevet i fuld managed code, og derfor arver direkte fra SystemException.
Så, enten skal du fange SystemException i dine klientklasser, hvilket ikke er særlig optimalt da ideen med try-catch jo netop er at man kan gøre noget forskelligt, alt efter hvilken exception der bliver kastet, eller du kan bruge det her trick:
en ny exception:
using System;
namespace MPAConsult.ToolBox.Data { /// <summary> /// Summary description for DataStoreException. /// </summary> public class DataStoreException : System.SystemException { public DataStoreException(string message, Exception exc) : base(message, exc) { }
public DataStoreException(string message) : base(message) { }
public DataStoreException() : base() { } } }
kast af den i facadeklassen:
public void Open() { if (conn.State == ConnectionState.Closed) { try { conn.Open(); } catch (OleDbException exc) { throw new DataStoreException(exc.Message, exc); } } }
og en anden:
public void Open() { if (conn.State == ConnectionState.Closed) { try { conn.Open(); } catch (MySqlException exc) { throw new DataStoreException(exc.Message, exc); } } }
og en tredie:
public void Open() { if (conn.State == ConnectionState.Closed) { try { conn.Open(); } catch (SqlException exc) { throw new DataStoreException(exc.Message, exc); } } }
på den måde kan du teste for DataStoreException i din klientclass, og være sikker på at fange evt. db-fejl, ligemeget hvilket facadeklasse du bruger.
det har du ret i arne... får dog stadigvæk emailnotifikationer, og selvom min pingtid kan være lidt lang (der er jo langt til Grønland), så kommer jeg da forbi i ny og næ :)
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.