Question 1 - practical
I run child process in my C# application using System.Diagnostics.Process. Like the following:
Process process = new Process();
// ... StartInfo initialization here
int timelimit_ms = 30000;
process.Start();
if (!process.WaitForExit(timelimit_ms))
{
// What exception to throw here?
throw new Excpetion(
"An executing method exceeded the time limit of " + timelimit_ms.ToString() + "ms");
}
I'm currently throwing System.ComponentModel.Win32Exception. But I don't sure it is the best choice. The child process is a simple command line utility. So the first question, what exception to throw in this situation?
Question 2 - thoretical
This is not the first time I ask myself about what exception to throw. And I don't know of a simple guidelines on how to pick a certain one. There are so much exceptions in C#, deeply inherited from one namespace to another. The second question, how to decide what exception to throw in a specific situation?
Practically, I'd throw a TimeoutException as it describes what is happening
Theoretically, if a quick google / read of the docs doesn't throw up an exception that already describes what is happening then you can just extend Exception to generate a WeirdThingThatHappensSometimesInMyApplication Exception.
But it depends who or what is going to "read" your exception. If your exception isn't exceptional then maybe you should do things differently :-)
how about a timeout exception?
I would think about throwing InvalidOperationException from the code.
As states MSDN, this exception is:
The exception that is thrown when a method call is invalid for the
object's current state.
So the caller of the function or consumer of the object that runs and waits for the process will be notified about the fact that execution of the function failed.
If you want to be detailed about declaration of the failure reason, you can express it
or in detailed message (if it's enough)
or create yuor own custom exception derived from InvalidOperationException and populate it with additional data you may need outside from the caller.
Related
What would be the most correct thing to do in a public API that uses Type.GetType(typeName) under the hood?
//inside a message deserializer of a framework...
....
//1. throw TypeLoadException
var type = Type.GetType(typeName,true);
//2. or..
var type = Type.GetType(typeName,false);
if (type == null)
throw new SomeMoreSpecificException("Could not find message type " + typeName +", deserialization failed");
//3. or
Type type;
try
{
type = Type.GetType(typeName,true);
}
catch(TypeLoadException x)
{
throw new SomeMoreSpecificException("some message",x);
}
Which of the above approaches would you consider the most helpful for the end user in this case?
I leaning towards the latter case here, as you get both the real TypeLoadException and some additional information specific for this very usecase.
Or should we just consider the TypeLoadException itself to be enough for the end user?
Thoughts?
[edit] for more context, see
https://github.com/akkadotnet/akka.net/issues/1279
In Akka.NET we can do "remote deployment" of actors.
if the remote system receiving the deploy request does not know about the type that should be deployed, we need to notify this somehow.
Only throwing TypeLoadException feels a bit cheap, as it does not pinpoint the problem to the remote deploy scenario.
There's not a right and wrong answer here. The trade off is having more details available in the thrown exception versus the overhead of having two exceptions throws (the original one and the custom one) instead of one.
The question is - what do you expect the user to do with the exception you're throwing? Does the "some message" you provide give more detail than the original exception? Or does it let the user do something different if it gets that specific exception type? If not, I'd just let the original exception bubble up.
Iam a newbie who needs help. When saving to a database, i get the following error:
A first chance exception of type 'System.Data.SqlServerCe.SqlCeException' occurred in (name of my application)
Please help me with steps to solve this one. Thank you in advance.
First chances exceptions will be shown if you have your Visual Studio settings set so that every CLR exceptions gets reported. This will include exceptions you actually handle.
In Visual Studio's menu, go to Debug > Exceptions and uncheck the Thrown option for Common Language Runtime Exceptions.
Of course that won't make the actual exception go away but you'll be allowed to handle it as you want:
try
{
// do your query
// commit current transaction if possible/necessary
}
catch (SqlCeException ex)
{
// handle exception here and rollback current transaction if possible/necessary
}
finally
{
// ensure proper disposal of any commands and connections you have
}
It goes without saying that you must ensure your query is properly written and that the server objects it tries to work with exists. You generally won't want to handle cases where a comma is missing or a field is not found, for instance. Exception handling must be for exceptional situations your code cannot control, like a faulted connection, a server malfunction, etc.
First of all you might want to check whehter your SQL query is syntactically correct.
Secondly you might want to read about how to handle exceptions in MSDN http://msdn.microsoft.com/en-us/library/0yd65esw.aspx with try-catch statement.
A small example looks like this.
try
{
// ... code which throws exception
}
catch (SqlCeException e)
{
// ... exception handling, e.g. logging, rolling back data,
// telling the user something went wrong, you name it
}
Last but not least you might want to debug your application step by step to see what is causing the error and what the actual SQL Query is throwing the exception.
Exceptions sometimes occur. When they do, they're logged and later analyzed. The log obviously contains the stack-trace and other global information, but often crucial context is missing. I'd like to annotate an exception with this extra information to facilitate post-mortem debugging.
I don't want to try{...}catch{... throw;} since that counts as catching an exception and that makes debugging harder (during development I'd like the app to stop and the debugger to react when the original exception is thrown, and not when the outermost uncaught exception is). First-chance exception handlers aren't a workaround since there are unfortunately too many false positives.
I'd like to avoid excessive overhead in the normal, non-exceptional case.
Is there any way to store key pieces of context (e.g. filename being processed or whatever) in an exception in a way that doesn't catch the exception?
I am taking a shot at this building off of Adam's suggestion of Aop. my solution would be Unity rather than postsharp and the only question I would have is whether the exception is being caught inside of invoke, which it likely is...
public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
{
//execute
var methodReturn = getNext().Invoke(input, getNext);
//things to do after execution
if (methodReturn.Exception != null)
methodReturn.Exception.Data.Add("filename", "name of file");
return methodReturn;
}
}
There is nothing wrong with the following pattern:
try
{
// Do Something
}
catch (GeneralException ex)
{
throw new SpecificException(
String.Format("More specifics ({0}) in message", someData),
moreContext,
new {even, more, context},
ex);
}
This is precisely the pattern to use, for instance, when the "Do Something" is to, say, open a file of some kind. The "SpecificException" might be "can't read configuration file".
I would not use AOP to catch the exceptions. Instead I would use the interception class to LOG the exception + all arguments to the method that threw the exception. And then let the original exception be thrown again
I have an unusual case where I have a very simple Exception getting thrown and caught in the same method. It isn’t re-thrown (the usual kind of problem naïve programmers have). And yet its StackFrame contains only one the current method. Here’s what it looks like:
at (my class).MyMethod() in C:\(my file path and line)
In reality there are probably 30 methods leading up to this in the VS2010 debugger's call stack, going across half a dozen different assemblies. It seems impossible for all that to have been optimized out. Moreover, this code is built in debug mode, without optimizations, for .NET 4. I even have (based on http://msdn.microsoft.com/en-us/library/9dd8z24x.aspx) .ini files (including one named [app].vshost.ini) in the same folder containing:
[.NET Framework Debugging Control]
GenerateTrackingInfo=1
AllowOptimize=0
Also, the method calls are not at the end of methods, so tail-recursion optimization seems further unlikely.
As to how it is called: there are no uses of reflection on the call stack, no Invoke() or BeginInvoke() of any kind. This is just a long chain of calls from a button click. The click handler is about 10 calls down the call stack. Beneath that you have the usual WndProc, NativeWindow.Callback, native/managed transitions, and message loop. This is ultimately inside a ShowDialog() call which is run from a C# EXE assembly.
Now, I found that I can construct instances of the StackTrace class in my catch handler, and if I pass the Exception object, the call stack is also short. If instead I just call new StackTrace() with no arguments, it yields a complete call stack.
I’ve used Reflector in an attempt to debug into the internals of the Exception class getting thrown and its call stack constructed, but I couldn’t set breakpoints in Exception or in StackTrace. I could set them in Environment.GetStackTrace() and this method (which Exception calls) does not appear to get called during the construction and throwing process, but I don’t know if the debugger is really working properly. (This method does get triggered for some other things though, so I'm not sure what to make of it.)
Here’s an excerpt of the method:
private void MyMethod()
{
...
try
{
throw new ApplicationException("Test failure");
}
catch (Exception e)
{
StackTrace stackTrace1 = new StackTrace(e);
StackTrace stackTrace2 = new StackTrace(e, false);
StackTrace stackTrace3 = new StackTrace(e, true);
StackTrace stackTrace4 = new StackTrace();
string STs = stackTrace1.ToString() + "\n---\n"
+ stackTrace2.ToString() + "\n---\n"
+ stackTrace3.ToString() + "\n---\n"
+ stackTrace4.ToString();
Log(EventSeverity.Debug, STs);
...
}
}
It’s really pretty simple: Throw exception, catch and log it.
I get the same results either in the debugger or when running standalone—a one-line call stack. And I know I have seen this problem elsewhere in our code base. Previously I had assumed it was due to re-throwing exceptions, but in a lot of cases it we log right inside the initial catch block. I’m quite baffled and all the web searching I’ve done hasn’t produce anything.
This is a little too much to add as a comment to the answer provided, but here's some more information:
I now see that this behavior is discussed at
http://dotnetthoughts.wordpress.com/2007/10/27/where-did-my-exception-occur/ and that it is actually described at http://msdn.microsoft.com/en-us/library/system.exception.stacktrace.aspx (though I think one could easily miss what they're saying there).
So I guess my "solution" will be a little hit-or-miss. We have a central method we usually call to format exceptions. Inside that method, I'll create a new StackTrace() both with and without the Exception object. Then I'll look for the method that is at the bottom of the Exception's stack trace, and display everything beneath that in the new StackTrace(), indicating it was called by that series of calls.
The down side of course is that if this method isn't used, the information won't be there. But I had to expect some kind of code change somewhere.
When an exception is thrown, only a partial stack trace will be used in the Exception.StackTrace property. The stack only shows calls up until the method that is catching the exception. To get the full stack (as you have noted) you should create a new StackTrace() object.
I can't find any links on it at the moment but I believe the stack trace is built by walking up the stack while throwing the exception. Once the exception reaches a catch block, the stack stops being compiled. Therefore, you only get a partial stack.
Typically, a catch block is not concerned with who called it, but where the exception is originating from.
I read a lot about how bad catching base Exceptions is and I have to confess that I did it also:
try{
...
}
catch (Exception exception){
MessageBox.Show(exception.Message, "Error!");
MyLogger.Log(exception.Message);
}
Now I would like to do it right and have some questions about it:
Which exceptions should I catch (for example FileNotExists for file manipulation, but what for TableAdapter or ReportClass (CrystalReports))
Where can I see a list of exceptions, that an objects can throw (for example TableAdapter)
Where in Windows Forms Application can I set a static method, which will log any exception to a file for example
Any other suggestions?
Catch whichever exceptions you can reasonably handle. For example, if you're trying to open a file for writing, you should expect that maybe the file is marked read-only, so that would throw an exception. But in the same situation you wouldn't try to catch a null argument exception, because that would be due to programmer error.
They should be found in the function reference in MSDN (you'll have to look it up on each one). For user-defined functions, you'll have to go digging, unless there is additional documentation or summary commentary.
3, 4. Consider using a logging library for .NET
I have one thing to add. If you just want to log an exception without affecting program flow you can always do this:
try
{
...
}
catch (Exception exception)
{
MyLogger.Log(exception.Message);
throw;
}
That's up to you to decide which exceptions your application logic can reasonably expect to recover from.
Exceptions are thrown by method invocations, not objects. In Visual Studio, Intellisense explanations will tell you which exceptions are thrown by an object (provided that the XML documentation describes which exceptions a method throws.
Rather than use a static method, respond to the Application.ThreadException event. The link provided has examples.
MSDN
You can set an event for unhandled exceptions in application events file
(got a VB sample here but i hope you get the point)
Private Sub MyApplication_UnhandledException(ByVal sender As Object, ByVal e As Microsoft.VisualBasic.ApplicationServices.UnhandledExceptionEventArgs) Handles Me.UnhandledException
End Sub
You can find the application events in the options of you project.
You should only catch exceptions you can do something about, really.
That's the rule of thumb. I typically have a try/catch around my Program.Main just in case an exception bubbles right to the top and needs logging. You can also handle the CurrentDomain_UnhandledException event, in case exceptions are thrown in other threads than the UI thread (assuming you are multithreading).
In response to "4. Any other suggestions?":
In your example code, a message box is displayed before logging the exception. I would recommend logging the exception before displaying the message, just in case the user sees the error message, panics, and goes on vacation without clicking "OK". It's a minor thing, but message boxes block the program indefinitely and should be used with discretion!