PDA

View Full Version : Error Handling در سطح global.asax



cemohsen
پنج شنبه 21 شهریور 1387, 17:27 عصر
با سلام
من قبلا خیلی اینجا در مورد ErrorHandling در سطح برنامه جستجو کردم ، اما چیزی پیدا نکردم
یه چیزایی پیدا کردم ، اما مشکلاتی دارم و ازتون کمک می خوام

من می خوام تمام خطاهای که تو سطح برنامه و کل صفحات دارم رو خودم مدیریت کنم و اونها رو ثبت کنم
برای این کار هم باید از Catch و Global.asax استفاده کنم
من از کدهای زیر استفاده می کنم ، اما جواب نمی ده

مثلا برای login کد زیر رو دارم

try
{
SqlConnection objConnection = new SqlConnection(Base.ConString);
SqlCommand objCommand = new SqlCommand();
objCommand.Connection = objConnection;

objCommand.CommandText = "SELECT * FROM admins";
objCommand.CommandType = CommandType.Text;

//Open Connection
objConnection.Open();

//Define DataReader for read data from sql
SqlDataReader objreader;
objreader = objCommand.ExecuteReader();

while (objreader.Read())
{
if (objreader.GetString(0).Trim().ToLower() != user)
return 1;

if (objreader.GetString(1).Trim().ToLower() != pass)
return 2;
}

return 3;

}
catch(Exception ex)
{
throw ex;
return 0;
}

ور برای global.asax هم این رو نوشتم

void Application_Error(object sender, EventArgs e)
{


Exception ex = Server.GetLastError();

Response.Write(ex.Message);

Server.ClearError();

}
و اینجاست که error میده

اما اگه تو کد global.asax از کد زیر استفاده کنم هیچ خطایی نمی ده و به صفحه ای که من می خوام Redirect می کنه

void Application_Error(object sender, EventArgs e)
{
Response.Redirect("default.aspx");
}

به نظر شما مشکل از کجاست ، من کجای کار اشتباه کردم ؟؟؟؟؟

anubis_ir
پنج شنبه 21 شهریور 1387, 23:47 عصر
Response.Write در اون فايل Global.asax اصلا معنا نداره.
خطاها رو بهتره در فايل ذخيره كنيد يا ايميل بزنيد. (يا حتي در event log ويندوز بنويسيد. اين مرسوم تر هست)
ضمنا كد شما نشتي حافظه داره! SqlConnection رو باز كرديد ولي جايي بسته نشده. همين مورد با 50 تا كاربر باعث كندشدن شديد اس كيوال سرور مي‌شود (بطوريكه سايت قابل استفاده نخواهد بود). SqlConnection را با استفاده از using مديريت كنيد.

cemohsen
جمعه 22 شهریور 1387, 13:53 عصر
سلام
مشکل من این چیز ها کهشما گفتی نیست دوست عزیز
من مشکلم اینه که چطور به سیستم حالی کنم که الان باید چه خطایی رو لاگ کنه و اون کدی که برای شما فرستادم یه Sample بود
و اینم بگم که میشه تو فایل Global.asax از Response.write استفاده کرد (من استفاده کردم و مشکلی هم باهاش ندارم)
بزارید کامل بگم

این کد برای Global.asax منه

// Get the exception object.
Exception exc = Server.GetLastError();

// Handle HTTP errors
if (exc.GetType() == typeof(HttpException))
{
// The Complete Error Handling Example generates
// some errors using URLs with "NoCatch" in them;
// ignore these here to simulate what would happen
// if a global.asax handler were not implemented.
if (exc.Message.Contains("NoCatch"))
return;

//Redirect HTTP errors to HttpError page
Server.Transfer("HttpErrorPage.aspx");
}


// Log the exception and notify system operators
Base.LogException(exc, "DefaultPage");




// Clear the error from the server
Server.ClearError();

و این کد هم برای LogException که به ازای هر روز یه لاگ درست می کنه

public static void LogException(Exception exc, string source)
{
// Include enterprise logic for logging exceptions
// Get the absolute path to the log file

string Today=DateTime.Now.Year.ToString()+DateTime.Now.Mo nth.ToString()+DateTime.Now.Day.ToString();


string logFile = "App_Data/ErrorLog" + Today +".txt";

logFile = HttpContext.Current.Server.MapPath(logFile);

// Open the log file for append and write the log
StreamWriter sw = new StreamWriter(logFile, true);
sw.WriteLine("********** {0} **********", DateTime.Now.TimeOfDay);
if (exc.InnerException != null)
{
sw.Write("Inner Exception Type: ");
sw.WriteLine(exc.InnerException.GetType().ToString ());
sw.Write("Inner Exception: ");
sw.WriteLine(exc.InnerException.Message);
sw.Write("Inner Source: ");
sw.WriteLine(exc.InnerException.Source);

}
sw.Write("Exception Type: ");
sw.WriteLine(exc.GetType().ToString());
sw.WriteLine("Exception: " + exc.Message);
sw.WriteLine("Source: " + source);

sw.Close();
}

که اینها مشکلی ندارن و تنها مشکل من اینه که وقتی تو Catch از کد زیر استفاده می کنم

catch(Exception ex)
{
_lblmessage.Text = ex.Message;

}
این خطا رو به من می ده که

An error has occurred while establishing a connection to the server. When connecting to SQL Server 2005, this failure may be caused by the fact that under the default settings SQL Server does not allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)
که درست هم هست ، چون من SQL رو بستم و Try هم نمی تونه Connection من رو Open کنه

اما وقتی از کد زیر تو Catch استفاده می کنم

catch
{
throw new Exception();
}

این اطلاعات رو برای من توی فایل لاگ ثبت می کنه که اون اطلاعاتی که من می خوام نیست

********** 14:00:00.2860400 **********
Inner Exception Type: System.Exception
Inner Exception: Unhandle Error
Inner Source: App_Web__ez8v6fv
Exception Type: System.Web.HttpUnhandledException
Exception: Exception of type 'System.Web.HttpUnhandledException' was thrown.
Source: DefaultPage

فکر کنم کامل توضیح دادم ، حالا باید چی کنم تا همون چیزی رو که می خوام لاگ کنم ؟؟؟

Behrouz_Rad
جمعه 22 شهریور 1387, 14:38 عصر
2 تا اشتباه مرتکب شدی.

1) GetLastError به تنهایی کافی نیست. خطاها سلسله مراتبی رو طی می کنن و یک خطا ممکنه به نوبه ی خودش خطای داخلی دیگه ای رو تولید کنه که از چشم برنامه نویس پنهان هست. بنابراین همیشه باید از متد GetBaseException استفاده کنی:


Exception exc = Server.GetLastError().GetBaseException();


2) پرتاب خط با استفاده از new اشتباست! در این حالت خطای جدیدی تولید می کنی که خطای اصلی رو لغو می کنه! فقط باید throw کنی تا خطای اصلی بتونه خودش رو تا بالاترین سطح ساختار کنترل خطایی که واسش در نظر گرفته شده برسونه و نابود نشه!
بنابراین کد ذیل اشتباست:


catch
{
throw new Exception();
}

و کد ذیل صحیحه:


catch (Exception ex)
{
throw ex;
}

موفق باشید.