Is there a way to use nested exceptions? I have this code "one the first level":
my func() { try { resp = Web.FormPostRequest(auth_url, authPost, "", url, cookies, type, proxy_string); } catch (Exception ex) { if (ex is xNet.ProxyException) { throw new xNet.ProxyException(); } if(ex is xNet.NetException) { //MessageBox.Show(ex.Message); throw new xNet.NetException(); //return false; } } } And on the "higher level" I've got this:
try { result = myfunc(auth_data[0], auth_data[1], Form1.domain, type, proxy_string); break; } catch (xNet.NetException ex) { { result = false; MessageBox.Show(ex.Message); return; } } The deal is that debugger always says that excpetion xNet.NetException wasn't handeled at line
if(ex is xNet.NetException) { //MessageBox.Show(ex.Message); throw new xNet.NetException(); //return false; } in myfunc(). What could it be and how do I resolve this? Thank you!
I change code to simpliest:
try { resp = Web.FormPostRequest(auth_url, authPost, "", url, cookies, type, proxy_string); } catch (Exception ex) { throw; } But even now visual stuido says that there is xNet.NetException that wasn't handled.
73 Answers
Could you just catch the specific exceptions you want to catch and let the rest "flow through"?
catch (xNet.ProxyException ex) { //re-throwing per the comment(s) in a smarter guy's answer. throw new Exception("Adding really important info here.",ex); } catch (xNet.NetException exToo) { //MessageBox.Show(ex.Message); //return false; //blah .. blah .. } We do that with SQL exceptions and it works really well. It lets us capture exactly the data we want to capture based on the specific error tossed off by SQL server (sorry for using 'tossed-off' in a stack post ... long day).
There are some rules that govern multiple catch blocks, but I'm too lazy to type them out here.
Also - in a blatent attempt to expand this answer to include an un-asked question - the format below is also valid for c# 6
catch (Exception ex) when (ex is xNet.ProxyException || ex is xNet.NetException) { //please go away... } Either way, you catch only what you intend to process, right? Then, if you need the stack in your outer catch block, take a look at innerException (because we are creating a little nested exception with your new data).
One Last (Minor) Note (edit)
Per the comments, it seems like the sample code you provide in your original question is throwing one type of error, but the outer catch block is catching a different error type.
INNER FUNCTION:
throw new xNex.ProxyException(); OUTER FUNCTION:
catch(xNet.NetException ex) ... Maybe that's just because you've made some edits to make this easier to read, but maybe check your code? Those mistakes are hard to see when you are dialed in!
8Unless you have a really good reason for creating new exception and swallowing all but those two types I would just change your catch block to rethrow the original exception in all cases:
catch (xNet.ProxyException ex) { // is there something you want to do here? throw; // let the caller handle all exceptions. } catch(xNet.NetException ex) { // is there something you want to do here? throw; // let the caller handle all exceptions. } catch { throw; // let the caller handle all exceptions. } If you're not going to do anything in either of the handlers, then you can just remove the entire catch block and let the exception bubble up naturally.
how do I resolve this?
Well, the first thing you should do is remove this entire catch block:
catch (Exception ex) { if (ex is xNet.ProxyException) { throw new xNet.ProxyException(); } if(ex is xNet.NetException) { //MessageBox.Show(ex.Message); throw new xNet.NetException(); //return false; } } Not only is it not actually doing anything to handle the exception, but it's explicitly throwing away the exception and replacing it with one that doesn't have any of the information about the error that occurred.
So the resulting method would simply be:
void MyFunc() { resp = Web.FormPostRequest(auth_url, authPost, "", url, cookies, type, proxy_string); } If the method does have some information to add to the exception, then you should at least preserve the original exception as well:
void MyFunc() { try { resp = Web.FormPostRequest(auth_url, authPost, "", url, cookies, type, proxy_string); } catch (Exception ex) { // do something here? throw new SomeExceptionType(ex); } } Or, if there's no new information to add (but still something meaningful to do), at least re-throw the original exception:
void MyFunc() { try { resp = Web.FormPostRequest(auth_url, authPost, "", url, cookies, type, proxy_string); } catch (Exception ex) { // do something here throw; } } But unless there's something you can do to actually handle or in any way respond to the exception, don't even bother catching it. It should only be caught by code which can meaningfully handle it.