Tja! Hej, Hej Johan, Jag använder mig av både try/catch och global.asax Ta även en titt på Microsofts "Exception Management Block" för ett ramverk för felhantering. Jag brukar helt enkelt försöka hantera felet så tidigt som möjligt där jag vet hur jag skall agera. Kan jag inte avhjälpa gå runt problemet men det finns releveant information att tillägga bäddar jag in detta i ett nytt exception och kastar det vidare. "men varför skulle du inte kunna styra loggning av/på från web.config och även t.ex ställa på vilken nivå som den skall logga ? Menar du att du inte skulle kunna läsa från web.config ifrån global.asax ?" Vi gör så att vi använder ApplicationBlocks.ExceptionHandling och låter exceptions oftast få bubbla upp till Application_Error Ola, Johan N, Ola, "Användaren borde fått meddelande "felaktigt värde ____ vg ändra.." Magnus, snygg lösning. Magnus, "Loggar du inte business exceptions?" Businessfel för mig är fel som inte uppföljer ett use case, ett användafall. "Dock tror även många att SOA även är då stora apps har ett eller två distribuerande gränsnitt mot omvärlden, men det är inte SOA. Var bara nyfiken hur din syn var på SOA då det vart en hel del hetsiga konversationer om detta. :-) " Okej tack för all input, mycket intressant läsning. SOA kan vi diskutera i en annan tråd gärna. =) Richard, Oki ska tänka på det. Detta var iofs bara en testapplikation där jag slängde in en connectionsträng in i sessionvariabel lite snabbt .. Men i övrigt hur tycker du/ni lösningen ovan ser ut? Rickard, Tack för den utförliga beskrivningen Johan, det är ungefär så jag också gör idag.Global felhantering best practise?
Har en arkitekturfråga här. Har läst lite på patterns & practises, men inte fått någon egentlig guideline VAR jag ska hantera mina fel i en säg webapplikation, och hur jag ska tänka. Jag vill inte använda ApplicationBlocks i detta projekt, jag vill ha maximal kontroll över fel och felhantering med egen kod.
I vanliga fall med "error-prone" kod ska man ju köra try/catch block. Absolut.
Fel som ligger utanför try/catch block då, vart ska jag hantera dem ? Min ganska uppenbara idé är ju såklart att sköta hanteringen i global.asax application_error. Kod:
<code>
Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs)
' Fires when an error occurs
Dim ex As Exception = Server.GetLastError
ExceptionHandling.LogItem(IIf(Not ex.InnerException Is Nothing, ex.InnerException, ex))
End Sub
</code>
ExceptionHandling.LogItem är en egen klass med logging till databas, sen tänkte jag kanske MSMQ som notifiering.
Sen tänkte jag att användaren som default ska dirigeras till: <customErrors defaultredirect="http://hostname/error.aspx" mode="on">
Men sen tänkte jag att det kanske är bättre att använda sig av en baskontroll och en baswebform som alla andra webforms och kontroller ärver från, och hantera felen i Page_Error på baskontrollen, Men det gick inte för det eventet kördes inte alls när det blev fel i ärvande kontroller.
Skulle vara fint om man bara behövde skriva logiken på ett ställen, och så vet alla ärvande kontroller och sidor hur de ska hantera felen, var felinformation ska presenteras till användaren, istället för att manuellt använda Try Catch överallt och reagera efter olika typer av Exceptions.
Hur skulle/brukar ni göra, och vad tycker ni om ovanstående förslag?Sv: Global felhantering best practise?
Global.asax gör det du vill ju. Du hanterar felen på ett ställe där, det är den globalaste punkt du kan hitta. Page_Errro är bara på sidnicå. Try o catch är bara på kodnivå.
Så jag anser du gjort rätt, varför krångla till det mer?
Mvh JohanSv:Global felhantering best practise?
Nädå jag vill inte krångla till, jag vill bara uppnå maximal effektivitet, användervänlighet, säkerhet och loggningsrutiner =) Hur brukar ni göra på webapplikationer ?Sv: Global felhantering best practise?
Först i min try/catch kod kontrollerar jag eventuella fel och om detta fel skall räknas som ett tekniskt- eller affärslogikfel, kan jag se att det skall vara ett affärslogikfel så wrappar jag in felet som jag fick in i mitt eget BusinessException objekt och kastar vidare, annars så kastas felet vidare.
I global.asax onError method så tar jag fram det senaste exception och gör sedan en server.Transfer till en speciell fel sida som tar hand om felet och loggar det samt skriver ut en fel text, och denna log samt feltext är olika beroende på om exception är en businessexception eller en annan exception.
så här ser koden ut i global.asax
//-- Get exception
Exception ex = Server.GetLastError();
//-- clear response
HttpContext.Current.Response.Clear();
//-- transfer to error page
Server.Transfer("/EnterpriseGateway/WebForms/error.aspx");
Och på min felsida så hämtar jag sedan fram felet igen.
//-- Get the last exception
Exception exception = Server.GetLastError();
if(exception is HttpUnhandledException && exception.InnerException != null)
exception = exception.InnerException;
Den nackdel som finns är att du inte kan stänga av/sätta på felhanteringen med hjälp av web.config utan den är alltid på och du måste förlita dig på din logg för att se den information du behöver.
- M
Sv:Global felhantering best practise?
Magnus --> Väldigt likt en metod som jag använder mig av, men varför skulle du inte kunna styra loggning av/på från web.config och även t.ex ställa på vilken nivå som den skall logga ? Menar du att du inte skulle kunna läsa från web.config ifrån global.asax ?Sv: Global felhantering best practise?
Jag försöker undvika generella catch satser, utan istället låta ohanterade fel fara vidare... som slutligen poppar upp till Global_asax.cs, och om inte tidigare så vet vi vad vi vill göra då... ge ett felmeddelande till användaren och logga så mycket du kan för att säkra upp att man slipper hamna i denna situation igen... ;-)
Mer kontroller och felhantering närmare källan ger större valmöjligheter. Till exempel har man kanske åtgärder som kan utföras för att gå runt/åtgärda problemet utan att det behöver synas för användaren.
Med andra ord, det beror på... kanske därför man inte får tydliga direktiv i Patterns and Practices?
Ha de gott !Sv: Global felhantering best practise?
Har jag faktiskt inte testat men det borde gå att läsa web.config från global.asax. Jag menar mer att den "vanliga" felhanteringen som finns i global.asax inte har någon inverkan hur felen presenteras eftersom jag själv hanterar det genom att gå vidare till en annan sida, men visst om man utvidgar koden i global.asax så borde man där kunna kontrollera inställningar i web.config och sedan utifrån de agerar på olika sätt.
- MSv: Global felhantering best practise?
där vi har en MailPublisher.
Det är ett jättebra sätt att hitta buggarna på.
Användare struntar ofta i exceptions (dvs de hör inte av sig)
utan hittar kanske sätt att komma runt det.
Då får vi aldrig reda på att det finns ett fel i applikationen på det stället, om det inte vore för MailPublishern som skickar iväg en stacktrace. Sv:Global felhantering best practise?
"... hittar kanske sätt att komma runt det. "
Vill man låta dem komma runt det? För vissa fel kan ju vara v den karaktär att saker bör stängas av, services, man kanske vill logga ut dem för att felet är så okänt och känsligt att man inte vill låta en massa sessions vara igång etc...
Mvh JohanSv: Global felhantering best practise?
"Vill man låta dem komma runt det? "
Det är väl olika från fall till fall. Finns det risker med det så ska det ju undvikas, samtidigt är det väl onödigt att försvåra för användaren ännu mer om det inte är nödvändigt (typ skicka till login-sidan för varje exception...)
Låt säga att man har missat felhanteringen av inmatade värden på ett ställe.
Användaren borde fått meddelande "felaktigt värde ____ vg ändra.."
i stället får dom ett exception. (Nej, det borde inte vara så, detta är en bugg jag beskriver nu).
Genom att backa tillbaks och fundera lite över vad man har matat in, kan det hända att användaren kommer på vad man kan göra för att undvika problemet.
Om man då inte har en MailPublisher eller annan loggning som kollas, kan det hända att användarna inte bryr sig om att rapportera in felet. Genom att publicera alla fel till utvecklarna kan man snabbt öka kvaliten i systemet, det är min erfarenhet!Sv:Global felhantering best practise?
Absolut, i ett sådant exempel. men det kan ju finnas andra exempel där man inte bör köra rebustness kod. Men det är ju mer eller mindre allvalrighetsnivån som styr detta.
Mvh johanSv:Global felhantering best practise?
i stället får dom ett exception."
Det där är en businessexception och inte en technicalexception, de 2 bör man skilja åt. Jag skulle aldrig få för mig att logga businessexceptions eftersom detta skulle genererar bra mycket mer felträffar än vad ett tecknisktfel innebär.
Men om det är som du säger att man "glömt valideringen" så kommer detta automatiskt bli ett teknisktfel eftersom du inte fångar felet själv och gör om det till ett businessfel.
Allt vad som är tekniska fel loggas ner i en databas (även dess innerexception) och grupperars ihop med ett XceptionId som jag har skappat, vilket betyder att jag enkelt kan gruppera ihop alla fel som hör ihop. Detta är extremt användbart vid en SOA lösning då det oftas är många olika system som skall anropas, om det då blir fel längst nere i kjedjan så kan jag följa alla fel hela vägen upp.
- MSv: Global felhantering best practise?
Det kanske jag ska implementera nån gång i framtiden.... Om jag får tid över... ;)Sv: Global felhantering best practise?
Loggar du inte business exceptions? Hur kan du då följa användarens klassiska misstag? Det finn sju fall då användaren inte säger till när saker går fel, sånt kan vara nyttigt för att ev identifiera brister i den interactions desgin man gjort etc... Businessexception kan i mina ögon mkt väl vara av teknisk karaktär också. Oftast är ju ett Businessexception ett fel som pekar mot ett use case och är det fel via ett use case så är det ju ett fel oavsett om det inte pajar hela applikationen.
Du tar även upp SOA och IDn? Blir lite tokig på denna hypade trend :-) säg inte att du bygger lokala applikationer där du kommunicerar via webservices istället för klassiska maschalings? Bara för att någon stålle predikar över att SOA skulle vara bäst? ;-)
När du pratar om ID syftar du på IDn unika för händelser i ditt system? Så som ett EventID i event loggen?
Mvh JohanSv:Global felhantering best practise?
Nope, inte rena business exceptions så som att det är fel personnummer, eller att det saknas pengar på ett konto osv osv, sådan fel logar jag inte i databasen utan bara slänger upp ett felmeddelande till lagret ovanför.
"Businessexception kan i mina ögon mkt väl vara av teknisk karaktär också"
Har du något exempel, för det är möjligt att vi ser olika på tekniska och businessfel (finns det inget bra ord för businessfel).
"Du tar även upp SOA och IDn? Blir lite tokig på denna hypade trend :-) säg inte att du bygger lokala applikationer där du kommunicerar via webservices istället för klassiska maschalings? Bara för att någon stålle predikar över att SOA skulle vara bäst? ;-)"
I min värld så är SOA inte samma sak som webservices! WebServices är bara ett transportprotokoll för att skicka data mellan olika tjänster. För mig är SOA inget nytt och magiskt utan bara en utbyggnad av gamla komponenttänket. Så istället för att bygga stora komplexa komponenter som jag kan referera till i min kod, så låter jag komponenten vara en egen lite tjänst som jag kan kommunicera med, om jag så väljer: WebServices, .NET Remoting eller DCOM är rätt ointressant. Fast just i det senaste projektet så var det webservices som gällde då det handlade om att integrera 4 olika plattformar, vilket gjorde att webservices var det enklaste valet. Och det är rätt trevligt att sammla alla felen från de olika plattformarna i en och samma log, riktigt j-vla trevlig för att citerar driftsfolket som innan har letat i massor med olika logfiler som ju inte kan gruppera felen och i flertrådade miljöer så är det svårt att hitta "flödet" i felen.
<i>När du pratar om ID syftar du på IDn unika för händelser i ditt system? Så som ett EventID i event loggen?</i>
Nope. När jag fångar ett exception som .NET kastar till mig, så wrappar jag in det felet i en egen Exception klass som ärver från en Xception basklass. Så när jag skapar ett eget fel och kastar så tilldelar jag min XceptionBaskklass ett XceptionId (en guid) och om jag senare i koden fångar detta egna fel och wrappar i ett nytt eget fel så kontrollerar jag om XceptionId är satt i det felet som jag fångar och wrapper och så fall använder jag i det nya felet som jag kastar, om det inte finns något xceptionid i felet som jag fångar så skapar jag ett nytt ID.
- MSv: Global felhantering best practise?
Tänker, Tänker... hum...
Kommer inte på nått specifikt just nu, då jag själv inte loggar som en tok. Men i ett system jag jobbar med i dagsläget har en del rena business cases som måste uppfyllas och dessa kan gå fel eller innehålla en bugg, då har vi valt att skriva ner sådant för att enklare spåra vad man ev gjorde innan eller just då felet uppstod. Vi kanske ser det på olika sätt. teknikst fel för mig är mer på en mycketlägre nivå, så som string är null, eller connection mot db fungerade inte. En transaction mellan ett usecase (businessrule) flipprar ur, detta kan mycket väl vara ett businessfel som i sin tur kan ha orsakats av ett tekniskt fel, men jag vill fortfarande veta på vilken nivå felet uppstod via någon identitet. I mitt fall kör vi med strängnamn (namespace-struktur) för att hitta i vilken tjänst felet uppstod. Detta för att det skall vara mer läsbart.
Jag är inte kritisk SOA i sig men dock sättet många missbrukar det på. Det finns de som bygger en massa intranetlösningar eller b2b apps som främst pratar internt med sig själv på ett SOA sätt. Bara för att några säger att SOA är bra. Dock tror även många att SOA även är då stora apps har ett eller två distribuerande gränsnitt mot omvärlden, men det är inte SOA. Var bara nyfiken hur din syn var på SOA då det vart en hel del hetsiga konversationer om detta. :-)
Mvh JohanSv:Global felhantering best practise?
Håller med om att SOA är ett hypat ord just nu och många tror att alla problem löses bara för att man bygger tjänster istället för komponenter. Det finns för och nackdelar med SOA precis som med alla andra lösningar, man måste bara väga dem emot varandra och sedan ta en beslutning vilken väg man skall gå.
- MSv: Global felhantering best practise?
Men som lösningen ser ut nu så använder jag mig av Application_Error() i Global asa. Ja, kan ju klistra lite kod:
<code>
Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs)
' Fires when an error occurs
Dim ex As Exception = Server.GetLastError
ExceptionHandling.LogItem(IIf(Not ex.InnerException Is Nothing, ex.InnerException, ex), Session("ConnectionString"))
End Sub
</code>
Och objektet ExceptionHandling tar emot hela Exception, loggar info från det, samt mer info (rekommenderat av best practise)
Sedan har jag inte bestämt mig om jag ska använda Server.Transfer, eller CustomErrorPage i Web.config.
Vad tycker ni om den lösningen ? Bu, Bä, bättre, sämre ?Sv:Global felhantering best practise?
Föredrar de att du lagrar connectionstring? Vilken best pract... då? Inte MS va? Pinsamt i så fall ;-)
Sedan så behöver du inte ha ConenctionString i en session, då du kommer ta upp minne för varje session som är igång, lägg den i appsettings istället och plocka den därifrån om du måste lagra den.
Så blir den global för hela applikationen.
Mvh JohanSv: Global felhantering best practise?
Jag delar upp felen i databasen och kallar det "systemfel" om felet kommer så långt fram till application_onerror .. eftersom de flesta fel fångas i trycatch block.
ps: Tackar för all input ovan!Sv:Global felhantering best practise?
Jag tror det är rätt väg.
De fel som jag lagrar via Global.asax är de fel som uppstår utan min egna kontroll. Alla andra fel hanterar jag där de kan inträffa oftast högt upp i nivån dvs så nära användaren som möjligt.
kör try o catch, logga fel där man förväntar sig att de kan uppstå. men gör det högt upp i lagerstrukturen, onödigt att fånga dem långt ner då du troligen ändå kommer villja hantera dem högre upp.
om fel uppstår utanför try och catch fångas dessa antigen av sidan (om något specialundantag måste ske) annars plockar global.asax dem åt mig.
Jag presenterar även två felsidor. Vid egna fel på sida och en annan felvisning om det blir ett globalt fel. Det globala felet är svårare att förutse och då brukar jag kasta upp ett formulär där jag ber användaren skriva vad de nyss försökte göra för att enklare kanske identifiera felet om GetLastError inte skulle ge så mycket.
Mvh JohanSv: Global felhantering best practise?
Då känns det som helt rätt väg och jag kommer fortsätta göra så i resten av mina lösningar =)
Informationen som loggas är en annan femma, men jag loggar samma saker som Microsoft rekommenderar i best practise. Funkar bra, och är tillräckligt beskrivande.
Sätter denna tråd som löst nu,
Puss & Kram