2009-07-14 16 views
5

Zastanawiasz się, co myślisz o tym rozwiązaniu, jeśli jest to właściwy sposób przekazania komunikatu o błędzie na niestandardową stronę?Najlepszy sposób przekazania ostatniego błędu do niestandardowego przekierowania błędu?

W web.config:

<customErrors mode="On" defaultRedirect="~/Error.aspx"></customErrors> 

W Global.asax:

<script RunAt="server"> 
    void Application_Error(object sender, EventArgs e) 
    { 
    Exception ex = Server.GetLastError(); 
    if (ex != null && Session != null) 
    { 
     ex.Data.Add("ErrorTime", DateTime.Now); 
     ex.Data.Add("ErrorSession", Session.SessionID); 
     HttpContext.Current.Cache["LastError"] = ex; 
    } 
    } 

</script> 

W moich Error.aspx.cs:

protected void Page_Load(object sender, EventArgs e) 
{ 
    if (IsPostBack) return; 

    if (HttpContext.Current.Cache["LastError"] != null) 
    { 
     Exception ex = (Exception)HttpContext.Current.Cache["LastError"]; 
     if (ex.Data["ErrorTime"] != null && ex.Data["ErrorSession"] != null) 
      if ((DateTime)ex.Data["ErrorTime"] > DateTime.Now.AddSeconds(-30d) && ex.Data["ErrorSession"].ToString() == Session.SessionID) 
       Label1.Text = ex.InnerException.Message; 
    } 
} 

wydania: Nie chcę zrobić Server. Transfer z Global.asax, ponieważ ... Nie wiem. Wydało mi się nieporęczne. Chcesz móc zmienić customErrors na RemoteOnly. Należy więc zapisać gdzieś ostatni wyjątek, ale nie może to być sesja, więc zapisz w pamięci podręcznej, ale z dodatkowymi danymi (time i sessionident), ponieważ pamięć podręczna jest globalna i chcesz się upewnić, że ktoś nie wyświetli błędnego błędu.


Zmieniłem trochę mój kod. Teraz to po prostu:

void Application_Error(object sender, EventArgs e) 
{ 
    HttpContext.Current.Cache["LastError"] = Server.GetLastError().GetBaseException(); 
    Server.ClearError(); 
} 

... i ...

protected void Page_Load(object sender, EventArgs e) 
{ 
    if (IsPostBack) return; 

    if (HttpContext.Current.Cache["LastError"] != null) 
    { 
     Exception ex = (Exception)HttpContext.Current.Cache["LastError"]; 
     if (ex != null) 
      Label1.Text = ex.Message; 
    } 
} 

Uwaga nie tam, jeśli użytkownik anonimowy, a sessionid ex.Data.Add klucz, który już nie będzie powodować błąd co mi zrealizować ważne jest, aby wywoływać ClearError

+0

Dla przypomnienia, stron, które wykonują przekierowania na błędy są naprawdę denerwujące, jak robią to dodatkowo trudne dla mnie, aby wysłać Ci URL, na których widziałem błąd lub ponownie później. –

+0

Dodatkowo Server.Transfer nie będzie działać dla niektórych częściowych postbacks stronę - robiliśmy to, ale to było w przypadku braku gdy błąd został zainicjowany z ciągu UpdatePanel – cloying

Odpowiedz

7

myślę, że to przyzwoity sposób to zrobić. Nie jest to sposób, w jaki to robię, ale mój kod jest zbyt długi, aby opublikować (i w VB.NET).

Jedna rzecz, którą chciałbym zmienić, to sama strona błędu. Zamiast wyświetlać błąd, rozważ dodanie pola tekstowego do strony błędu jako opcjonalnego pola, w którym użytkownik może wprowadzić swój adres e-mail i kliknij przycisk, aby wysłać raport o błędach. Następnie, po otrzymaniu raportu o błędzie, możesz spojrzeć na problem i odpowiedzieć na nie. Jest to o wiele bardziej przyjazny dla użytkownika sposób, który sprawdza się w przypadku witryn, w których to zrobiłem.

Wzdłuż tych linii, można też chcą gromadzić dane formularzy, dane sesji i wszystko inne wartości i umieścić, że także w raporcie o błędach. Może to znacznie ułatwić diagnozowanie problemów.

+0

+1 Dobra odpowiedź - podoba mi się pomysł, aby dać użytkownikowi trochę miejsca na wysłanie e-maila. Tak naprawdę nie możemy tego zrobić ze względu na wielkość naszej bazy użytkowników, ale rejestrujemy wszystko w bazie danych. –

+0

Dzięki, udało nam się to dobrze. W naszej największej witrynie mamy ponad 50 000 użytkowników, którzy ukończyli naszą 15-20-stronicową aplikację online. A to, co odkryłem na temat tej techniki, to to, że tworzy poczucie pilności z powodu oczekiwań użytkownika i mojego. Ma sposób na zmotywowanie mnie do wyeliminowania wszystkich błędów. A kiedy już to zrobię, spędzam znacznie mniej czasu na wspieraniu strony internetowej, a więcej na jej ulepszaniu. –

+0

Aby to rozwinąć, nie mogę wystarczająco podkreślić, jak ważne jest dobre zgłaszanie błędów. To naprawdę pomaga, gdy otrzymujesz wiele szczegółów, które powodują błąd w kontekście. Na przykład, jeśli dokonasz iteracji za pomocą każdej pary klucz/wartość formularza i uwzględnisz ją w raporcie o błędzie, wiesz, co użytkownik wprowadził w formularzu. –

1

Ponieważ pamięć podręczna jest globalna, nie byłoby to zalecane, ponieważ powiedziałeś, że ktoś może wyświetlać błędny błąd. Powinienem również powiedzieć, że nie powinieneś wyprowadzać komunikatu o błędzie bezpośrednio do użytkowników końcowych ze względów bezpieczeństwa.

Wystarczy popatrzeć na ten problem:

ASP.NET custom error page server GetLastError is null

podsumować umieścić coś jak następuje:

Server.Transfer(String.Concat("~/Error.aspx?message=", HttpUtility.UrlEncode(ex.InnerException.Message))) 

zamiast polegać na ASP.NET zrobić przekierowanie za pomocą ustawień w sekcja CustomErrors.

+1

+1 - Zgadzam się, że nie powinno pokazać błąd do użytkownik. Zapisujemy go w bazie danych, tak jak opisuję w mojej odpowiedzi. –

1

Robimy coś, co może, ale nie musi, działać. Wykonujemy obszerne logowanie w DB. Gdy pojawi się błąd, rejestrujemy go i generuje identyfikator błędu. Przekierowujemy na stronę ogólną z identyfikatorem błędu i otrzymujemy szczegóły.

oczywiście ten spada płasko na jego twarzy, gdy błąd jest „nie można połączyć się z DB”, ale to nie zdarza się zbyt często;)

+0

+1 Ode mnie - moja odpowiedź jest nieco inna, ale używamy także rejestrowania DB, więc przegłosowałem ciebie. –

1

musiałbym zgodzić się z obu n8wrl i Steve, że lepszym rozwiązaniem byłoby błędy w bazie danych logowania, a następnie powrócić tylko identyfikator błędu dla użytkownika. Naprawdę nie muszą widzieć szczegółów technicznych i możliwe, że ujawni to poufne informacje.

W naszym przypadku przekazujemy również identyfikator użytkownika (jeśli jest dostępny) i stronę, na której wystąpił błąd (Request.URL jest nadal dobry, gdy dojdziemy do globalnego Application_Error). W ten sposób możemy łatwiej wykryć błąd. Zauważ także, że nie musisz używać Global.asax z tagiem skryptu. Jeśli utworzysz plik Global.asax.cs w katalogu App_Code, możesz po prostu zakodować kod C# bezpośrednio (może to jednak zależeć od typu projektu).

0
Server.ClearError(); 

Ten wiersz powinien zostać umieszczony na Error.aspx.cs po wyświetleniu komunikatu ErrorMessage, które moim zdaniem.

+0

Wierzę, że to uniemożliwi zalogowanie się błędu do dziennika zdarzeń systemu Windows w domyślnej konfiguracji. – Sam

0

Byłem odpowiedzialny za tworzenie niestandardowej strony błędu. Wszystko było bardzo proste: w pliku web.config miałem:

<customErrors mode="On"> 
<error statusCode="404" redirect="~/error-pages/page-not-found.aspx?error=1" 
</customErrors> 

iw Global.asax w sposobie Application_Error: jakiś kod ...

Server.Transfer("~/error-pages/error.aspx"); 

W błędu niestandardowego strona "error.aspx": Server.ClearError();

Nie wiem dokładnie, co zostało zmodyfikowane, ale to już nie zadziałało. Gdy kod osiągnął metodę Server.Transfer wyjątek zawsze podniesiona: Błąd podczas wykonywania żądania dziecko do strony ...

Spojrzałem na niektórych rozwiązań i wreszcie, że ten jeden. zmodyfikowałem mój kod, a teraz wydaje się działać:

<customErrors mode="On" defaultRedirect="~/error-pages/error.aspx"> 
    <error statusCode="404" redirect="~/error-pages/page-not-found.aspx?error=1" /> 
</customErrors> 

iw sposobie global.asax:

Session["LastError"] = Server.GetLastError(); 

to działało także z Cache [ ""] kod, ale wolałem zmienna sesji.

Dzięki za odpowiedzi.

  • Nie zapomnij usunąć błędu na stronie błędów niestandardowych. To jest ważne. Ponadto wskazane byłoby, aby nie pokazywać dokładnie całego błędu dla użytkownika. Może w pewnym przyjaznym dla użytkownika formacie. I podaj wszystkie informacje w pliku dziennika lub wyślij go e-mailem lub czymś innym.

Nadzieja ta była użyteczna.

Powiązane problemy