How to log exception parameter values - asp.net

I have a asp.net website.
In this website I have made many function, these function are called inside another function. I want to write all the data that was passed to the function along with the value to a log file.
let us suppose an example
public void MyFunction(int a, int b)
{
try
{
int result=a/b;
}
catch
{
Some Code Here so that I can catch the exception and write into my log file like
/**Function Name: MyFunction**/
/**Parameter a=9;**/
/**b=0;**/
}
}
I have searched for postsharp but it doesnt work with website.

use a try/catch block
i.e.
try {
// call a method
} catch(Exception e) {
// an error occurred, details are in the local variable e
}

Assuming you are using a function/method that is part of the .NET library then you can check the documentation which will list all of the possible exceptions. E.g. See "Exceptions": http://msdn.microsoft.com/en-us/library/b9skfh7s.aspx
You can then use try/catch to catch any exceptions that may be thrown.

Take a look at ELMAH.
It is quite is to install and configure.
You will be up and running in no time.
If you want to log also info about passed in parameters I would just rethrow an exception which contains all this info.
Elmah will record it for you
** EDIT **
Here you have a tutorial on how to get up and running.
I recommend that you use nuget, here is a nice step through:
elmah-using-nuget-what-they-are-and-why-you-should-use-them-part-1/

Related

is it necessary to revert something when using return inside a changeCompany

I have to add a control inside a changeCompany() in an existing class.
I suppose the code below is OK, but I have a doubt : Does the "return" order imply that a return to the original company is done ?
Or is there to add a statement, unknown by me, something like revertToPreviousCompany()?
try
{
changeCompany(companyId)
{
// the method will produce a message and return false if an error
if (!this.doSomeChecks()) {
return;
}
// much more code below
Yes that is OK as in some situations you wouldn't even be able to revert it if not done by the runtime itself.
Imagine a callstack in which you have try - catch around some code your are calling and you expect there may be thrown an error but if the code which calls your code already established a transaction your handler is not called and therefore you wouldn't have a chance to undo the changeCompany

How can I handle exceptions in WebAPI 2. methods?

In my WebAPI 2.1 application I am processing inserts like this:
[Route("Post")]
public async Task<IHttpActionResult> Post([FromBody]City city)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
try
{
db.Exams.Add(city);
await db.SaveChangesAsync(User, DateTime.UtcNow);
}
catch (Exception ex)
{
var e = ex;
return BadRequest("Error: City not created");
}
return Ok(city);
}
I use something similar for updates and deletes. I think I should do something more meaningfull with
the exceptions but I am not sure where to start with how to handle these. I looked at elmah but it said it deals with unhandled exceptions. Does this mean I should not be catching exceptions like this?
Can someone give me some
pointers as to if what I have is okay and also should I be logging exceptions and how?
What you are doing is not "bad", it's just a bit verbose and won't scale well if you have many try/catch blocks all over your code. When an exception is raised, you decide what to do so, returning a bad request response is fine if it's really a bad request. There are many things you can return, depending on what went wrong. But you have to handle what to do when exceptions are thrown all over your code, so maintaining this logic scattered all over your code can quickly become a problem.
It's better to utilise asp.net web api's exception handling framework. For example, take a look at these articles:
http://www.asp.net/web-api/overview/web-api-routing-and-actions/exception-handling
http://www.asp.net/web-api/overview/web-api-routing-and-actions/web-api-global-error-handling
The idea is to centralise your logic in a global exception handler and to use that as the only place in your code where you have to worry about this. The rest of your code will be throwing exceptions and everything will be coming through your exception handler/filter/etc., depending on what you decide.
For example, I have created my own exception types (e.g. CustomExceptionA, CustomExceptionB, etc.) and when I throw an exception of a type I know exactly how to handle it in one place and perform a certain bit of logic. If I want to change the way I handle a particular exception type, then there's only one place I have to make a change and the rest of the code will be unaffected.
The second article link above also includes a global exception logger to log such exceptions.

How can i get Application_UnhandledException details in silverlight/ASP.NET

private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
{
if (!System.Diagnostics.Debugger.IsAttached)
{
e.Handled = true;
Deployment.Current.Dispatcher.BeginInvoke(delegate { ReportErrorToDOM(e); });
}
}
I have a solution with a silverlight application (that calls a webservice) being hosted in an asp.net application.
If there is any unhanded exception in the application, i want to get as much detail as can be possible e.g the exception message, innerexception details, file where exception occurred, method which was being called.....just like what i would get in a catch block.
So from the Application_UnhandledException event above, how can i get this information from the ApplicationUnhandledExceptionEventArgs e?
e.ExceptionObject.ToString()
is better than the default from the wizard in that it also gives you nested exception names, messages and stack traces.
Method names are included in the stack traces.
File names and line numbers, however, are not retrievable from Silverlight by any method I know of, even when running with elevated privileges.

Flex: recover from a corrupt local SharedObject

My Flex app uses local SharedObjects. There have been incidents of the Flash cookie getting corrupt, for example, due to a plugin crash. In this case SharedObjects.getLocal will throw an exception (#2006).
My client wants the app to recover gracefully: if the cookie is corrupt, I should replace it with an empty one.
The problem is, if SharedObject.getLocal doesn't return an instance of SharedObject, I've nothing to call clear() on.
How can I delete or replace such a cookie?
Many thanks!
EDIT:
There isn't much code to show - I access the local cookie, and I can easily catch the exception. But how can I create a fresh shared object at the same location once I caught the exception?
try {
localStorage = SharedObject.getLocal("heywoodsApp");
} catch (err:Error) {
// what do I do here?
}
The error is easily reproduced by damaging the binary content of a Flash cookie with an editor.
I'm not really sure why you'd be getting a range error - esp if you report that can find it. My only guess for something like this is there is a possibility of crossing boundries with respect to the cross-domain policy. Assuming IT has control over where the server is hosted, if the sub-domain ever changed or even access type (from standard to https) this can cause issues especially if the application is ongoing (having been through several releases). I would find it rather hard to believe that you are trying to retrieve a named SO that has already been named by another application - essentially a name collision. In this regard many of us still uses the reverse-dns style naming convention even on these things.
If you can catch the error it should be relatively trivial to recover from: - just declare the variable outside the scope of the try so it's accessible to catch as well. [edit]: Since it's a static method, you may need to create a postfix to essentially start over with a new identifier.
var mySO:SharedObject;
....
catch(e:Error)
{
mySO = SharedObject.getLocal('my.reversedns.so_name_temp_name');
//might want to dispatch an error event or rethrow a specific exception
//to alert the user their "preferences" were reset.
}
You need to be testing for the length of SharedObject and recreate if it's 0. Also, always use flush to write to the object. Here's a function we use to count the number of times our software is launched:
private function usageNumber():void {
usage = SharedObject.getLocal("usage");
if (usage.size > 0) {
var usageStr:String = usage.data.usage;
var usageNum:Number = parseInt(usageStr);
usageNum = usageNum + 1;
usageStr = usageNum.toString();
usage.data.usage = usageStr;
usage.flush();
countService.send();
} else {
usage.data.usage = "1";
usage.flush();
countService.send();
}
}
It's important to note that if the object isn't available it will automatically be recreated. That's the confusing part about SharedObjects.
All we're doing is declaring the variable globally:
public var usage:SharedObject;
And then calling it in the init() function:
usage = SharedObject.getLocal("usage");
If it's not present, then it gets created.

Is there a way of showing variable values in an global ASP.Net exception?

I have a global error trap in the Application_Error method of Global.asax that writes any unhandled exception to a log file.
Is there anyway of reporting the variable names and their values as part of the exception report?
Unless you do something really tricky with Aspect-Oriented Programming, you pretty much need to make sure that you manually introduce any relevant information into the stack trace when exceptions are thrown. For example:
public void DoSomething(int number, string name)
{
try
{
...
}
catch (Exception e)
{
throw new Exception("Error occurred while doing something: " +
new {number, name}, e);
}
}
This way, the number and name will be included in the stack trace when this exception trickles up to the top level.
Edit
After reading David Stratton's answer, I felt the need to expand on this a little. I get the sense that even some very experienced C# programmers haven't learned some of the tricks that I've learned.
First of all, I wanted to point out that the exception-handling system in .NET was designed with the idea of an InnerException specifically for this purpose (providing additional information at various points of the stack trace), and it is not at all hacky to do. However, you should definitely provide the exception as the innerException constructor parameter, rather than appending e.ToString() to the new exception's message.
Secondly, based on various comments and answers I've read on StackOverflow, as well as my own experience, it's best to:
Avoid catching an exception if there's nothing specific you plan to do with it.
When you catch an exception, rethrow it unless you know why the exception was thrown and you're in a scope where you know how to gracefully retreat from what you were trying to do. Simply pretending nothing went wrong is asking for more trouble down the road.
When re-throwing exceptions, either just throw; to preserve the original exception's stack trace, or include the original exception as a new exception's InnerException.
Consistently log exceptions that don't get re-thrown. This will generally only happen at the UI level, so you can tell the user something unexpected happened rather than allowing the program to crash.
Finally, I wanted to mention that the anonymous type declaration syntax is ideal for this kind of thing because it is very concise and it will automatically produce a string that uses the given variable names and values. For example, new {number, name}.ToString() might produce "{ number = 1, name = Test }".
We do this in some cases, but in a roundabout way. We use a try/catch at the granular level and if we want to pass the exception up to the global error handler, we build the error message. For example:
int someCounterValue = 0;
string someStringValue = "Some string we want to track to send to the global error handler."
private void SomeFunction()
{
try
{
someStringValue = "in the try block";
someCounterValue = 1.5 // should thrown an exception
}
catch(Exception ex)
{
throw new Exception("Error in SomeFunction. someStringValue = " + someStringValue + "; someCounterValue = " + someCounterValue.ToString() + "\r\nException details: " + ex.ToString());
}
}
It's a lot of work so we really don't do this very often. Usually our error handling is better handled at the local level but in those very rate cases where you want to pass it off to the global error handler, this is about the only way we've found, since the variables would be out of scope otherwise, and therefore, inaccessible.
An easier/less hack-like option would be to set up a static class in your web app called ErrorLogger or something similar, and just handle the exceptions better locally and pass them up to the global handler ONLY when you can't do it locally.
In my opinion (and in the way we do it here by policy) a global error handler should be used to catch exceptions that you forgot to handler better at a more granular level. It should NOT just be an easy way to be lazy about proper exception handling.
Also it feels like a hack to me, so if anyone has a better option I'd like to know it, too.

Resources