I am getting error Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack. while executing line
Server.Transfer("Payment.aspx?vpc_ChannelId=2", true);
so as pointed out by this answer https://stackoverflow.com/a/1252119/1169180 & https://stackoverflow.com/a/11130517/1169180
i changed my code to
protected void Page_Load(object sender, EventArgs e)
{
try
{
UserContext conObj = new UserContext();
HttpContext CurrContext = HttpContext.Current;
if (!IsPostBack)
{
// Code
}
else
{
string userContext = hdnContextObj.Value;
conObj = JsonConvert.DeserializeObject<UserContext>(userContext);
CurrContext.Items.Add("Context", conObj);
try
{
Server.Transfer("Payment.aspx?vpc_ChannelId=2", true);
}
catch (ThreadAbortException xObj)
{
}
finally
{
Server.Transfer("Payment.aspx?vpc_ChannelId=2", true);
}
}
}
catch (Exception xObj)
{
Response.Write("Exception : " + xObj.Message);
}
}
still i am getting same exception in out catch block
Also as pointed out here http://support.microsoft.com/kb/312629/EN-US/ i used Server.Execute but it didnt redirect to Payment.aspx page instead it just refreshes.
The exception is raised because the thread running the operation is forced to terminate in multiple locations due to the transfer. As such, it is safe to ignore this exception as your linked answers suggest.
You can ignore the exception by catching the exception and not throwing it.
try
{
Server.Transfer("Payment.aspx?vpc_ChannelId=2", true);
}
catch(ThreadAbortException)
{
// Exception ignored: Thread Abort = discontinue processing on the current page
}
Alternatively, as the MSDN article suggest, you can use Server.Execute instead.
To work around this problem, use one of the following methods:
For Response.End, call the HttpContext.Current.ApplicationInstance.CompleteRequest method instead of Response.End to bypass the code execution to the Application_EndRequest event.
For Response.Redirect, use an overload, Response.Redirect(String url, bool endResponse) that passes false for the endResponse parameter to suppress the internal call to Response.End. For example:
Response.Redirect ("nextpage.aspx", false);
If you use this workaround, the code that follows Response.Redirect is executed.
For Server.Transfer, use the Server.Execute method instead.
// Clarification on Server.Execute
The MSDN doc clarifies the usage of Server.Execute. It is important to remember this is not a redirect, it acts like a function call. So any code after the call will also be executed. If you do not want the code to execute you can use a return, or Response.End.
In the OP's example, his code might look something like this when using Server.Execute
protected void Page_Load(object sender, EventArgs e)
{
try
{
UserContext conObj = new UserContext();
HttpContext CurrContext = HttpContext.Current;
if (!IsPostBack)
{
// Code
}
else
{
string userContext = hdnContextObj.Value;
conObj = JsonConvert.DeserializeObject<UserContext>(userContext);
CurrContext.Items.Add("Context", conObj);
Server.Execute("Payment.aspx?vpc_ChannelId=2", true);
Response.End(); // or return;
}
}
catch (Exception xObj)
{
Response.Write("Exception : " + xObj.Message);
}
}
Server.Transfer("Payment.aspx?vpc_ChannelId=2", false);
This will work for you. It stops the rest of the remaining code after the transfer code, so that it will not execute that code.
ThreadAbortException exception caused because Response.End called both in Server.Redirect and Server.Transfer internally.Try something like this
Response.Write("<script language=\"javascript\" type=\"text/javascript\">window.location.href = 'Your.aspx'; </script>");
Related
How to check if a function throws an exception in c#?
public List<string> GetFileNames()
{
try
{
// do something
// return something
}
catch(Exception ex)
{
// do something
// log something
}
}
then i will call GetFileNames() somewhere in my code, but I want to check if it throws an exception,
like,
var list = GetFileNames(); // can be 0 count
if(GetFileNames() throws an error)
{
DoThisMethod()
}
else
{
DoThisOtherMethod();
}
You have a lot of options here:
This is generally done with a Try... pattern like TryParse.
bool TryGetFileNames(out List<string> fileNames)
You can also return null.
You can"t do this in c#.
The closest thing to what you are describing is the "checked exceptions" which are implemented in java. In such case the function will declare it is throwing some exception like so :
public void foo() throws IOException {
// your code
}
At compile time you will be forsed to take care of this by either enclosing this in TryCatch block or propagate this the same way in your function.
In c# enclose the function in TryCatch block and use different function in case of faliure.
The fundamental problem is that you're attempting to handle an exception when you're not able to do so.
If GetFilenames cannot recover from the exception, it should throw an exception itself. That may be by omitting a try/catch entirely, or by catching it, wrapping and re-throwing.
public List<string> GetFilenames() {
try {
...
} catch (Exception e) {
throw new FileLoadException("Failed to get filenames", e);
// Or if you don't want to create custom exceptions, perhaps use an InvalidOperationException
}
}
Failing that, if you don't actually need to abstract the functionality, don't catch the exception in GetFilenames at all, then call it like this:
try {
var list = GetFilenames()
DoSomething();
} catch (Exception e) {
DoSomethingElse();
}
I think you can make it simpler:
public void ICallGetFileNames()
{
var list = new List<YourObject>();
try
{
list = GetFileNames();
DoThisOtherMethod();
}
catch (Exception ex)
{
DoThisMethod();
}
}
This way, if the exception is thrown by your GetFileNames method, the DoThisOtherMethod() won't be called, since your code is going directly to the Exception block. Otherwise, if no exception is thrown, your code will call the DoThisOtherMethod just after the GetFileNames method.
I am working on an ASP.Net project where we have an centralized redirection method. But some times it throws an exception:
System.Threading.ThreadAbortException
The main problem is that often the code execution is not stopping after calling SBA.Redirect("AnotherPage.aspx") and the following code is still executing.
My generic function:
public static class SBA
{
public static void Redirect(string Url)
{
try
{
HttpContext.Current.Response.Redirect(Url, false);
HttpContext.Current.ApplicationInstance.CompleteRequest();
}
catch (Exception ex)
{
if (ex.GetType() != typeof(System.Threading.ThreadAbortException))
{
throw;
}
}
}
}
Redirect raises a ThreadAbortException specifically in order to stop any following code from being run.
You are handling the ThreadAbortException.
Thus the following code is being run.
If you don't want the following code to be run, don't handle the ThreadAbortException.
Simply make the following call to make a redirect:
HttpContext.Current.Response.Redirect(Url);
There are two problems with your code:
You use an overload of Redirect where you decide to not end the response by supplying false for the endResponse parameter. Hence the code after the redirect executes.
You try to catch ThreadAbortException. When using the normal redirect as described above this exception is thrown. It is not an error condition but simply a way for ASP.NET to ensure proper termination of the current request. You can catch the exception but it is rethrown at the end of the catch block so your catch block will not do anything useful.
Because an exception is thrown when redirecting you should be aware of the following explained in the comment:
void HandleRequest() {
try {
Response.Redirect(" ... url ... ");
}
catch (Exception) {
// Code here will execute after the redirect.
}
}
To avoid problems the best thing is to catch a more specific exception type in the catch handler or at least not do anything in the handler that interferes with the redirect (like writing to the response stream).
I protected the redirection using the code below. It's working.
public static class SBA
{
public static void Redirect(string Url)
{
try
{
//redirect only when 'IsRequestBeingRedirected' is false
if (!HttpContext.Current.Response.IsRequestBeingRedirected)
{
Uri uri = null;
bool isUriValid = Uri.TryCreate(Url, UriKind.RelativeOrAbsolute, out uri);
if (!isUriValid)
{
throw new SecurityException("Invalid uri " + Url);
}
//Below check is not required but checked
//to make obsolate security check
if (uri.OriginalString == null)
{
throw new SecurityException("Invalid uri " + Url);
}
// check if host is from configured trusted host list
if (uri.IsAbsoluteUri)
{
var tempAppSetting = ConfigBLL.GetAppSetting(AppSettingSectionType.OtherSetting).Other;
if (!tempAppSetting.RedirectTrustedUrls.Contains(uri.Host))
{
throw new SecurityException("Untrusted url redirection detected. Can not redirect.");
}
}
var tempUrl = uri.OriginalString;
//Few more logical check
HttpContext.Current.Response.Redirect(tempUrl, true);
}
HttpContext.Current.ApplicationInstance.CompleteRequest();
}
catch (Exception ex)
{
if (ex.GetType() != typeof(System.Threading.ThreadAbortException))
{
throw;
}
}
}
}
I have following code in my web page:
btnTest_Click(object sender, EventArgs e)
{
...
bool ret=myFunc(...);
if (ret)
{...}
else
{
lblStatus.Text="Some Text";
lblStatus.Visible=true;
}
}
private bool myFunc(...)
{
bool ret=false;
try
{
...
ret=true;
}
catch (Exception ex)
{
lblStatus.Text="Other Text";
lblStatus.Visible=true;
}
return ret;
}
If an exception occurs in myFunc, the lblStatus always shows "Some Text" not "Other Text". That means the catch block in myFunc doesn't really mean anything. I wonder how to fix this code to handle the exception better?
update: maybe my example is not very good. But I main purpose is to ask best practices for exceptions handling between calling and being called functions.
Why is your called function setting the label text on exception and the caller setting it on success?
That's something of a mixed metaphor. Let one party be responsible for UI (separation of concerns) while the other is responsible for doing work. If you want your called function to be fault tolerant try something like this:
private bool myFunc(...)
{
bool ret ;
try
{
...
ret=true;
}
catch
{
ret = false ;
}
return ret;
}
Then your caller can do something like:
bool success = myFunc(...) ;
lblStatus.Text = success ? "Some Text" : "Other Text" ;
lblStatus.Visible = success ;
if ( success )
{
// do something useful
}
Your catch clause is doing a lot. It catches every exception and "forgets it" suppressing it to the rest of the call stack. This can be perfectly fine but i'll try to explain your options:
You usually have 3 options:
Do not care about exceptions and let code above you handle it
Care to log the exception and let it propagate
The exception has its meaning in a given context and should not be propagated (this is your scenario)
I use all of them.
Option 1
You can just implement your function and if an exception occurs then it means some fault occurred and you just want your application to fail (at least to a certain level)
Option 2
Some exception occurs and you'll want to do one of two (or even both)
log the error
change the exception to another one more meaningful to the caller
Option 3
The exception is expected and you know how to completely react to it. For instance, in your case, i tend to believe you do not care about the type of exception but want a "good default" by setting some controls to a given text.
conclusion
There are no silver bullets. Use the best option for each scenario.
Nevertheless catching and "suppressing" catch(Exception ex) is rare and if seen often it usually means bad programming.
It displays "Some Text" because, when an exception occurs in myFunc, it returns false. Then you go into the else block of the btnTest_Click method, where you set lblStatus.Text to "Some Text" again.
So, basically, you're setting the label's text to "Other text" and then to "Some Text".
The exception handling is just fine. The problem with your code is that you are putting the "Some Text" string in the label if the return value is false, and that is when there was an exception, so it will replace the message from the catch block.
Switch the cases:
if (ret) {
// it went well, so set the text
lblStatus.Text="Some Text";
lblStatus.Visible=true;
} else {
// an exception occured, so keep the text set by the catch block
}
This is a complex question so I will try to break it down
In terms of functions I would try to stick to the Single Responsibility Principal. It should do one, well defined thing.
Exceptions should be that, exceptional. It is then preferable to try not to incur exceptions but obviously to deal with them as and when. For example it is better to test a variable as being null before attempting to use it (which would throw an exception). Exceptions can be slow (especially if a lot are thrown)
I would say that the question of WHERE you handle the exception is down to whose responsibility the exception is. If myFunc were to access a remote server and return a status of true or false you'd expect it to handle its own IO exception. It would probably not handle (or rethrow) any parameter problems. This relates to point 1. It is the functions responsibility deal with the connection process, not to provide the correct parameters. Hiding certain exceptions can cause problems if other people (or a forgetful you) tries to use the code at a later date. For example in this myFunc which makes a connection, should you hide parameter exceptions you may not realise you have passed in bad parameters
If you want to be informed of encountering a specific type of error inside one of your functions, I'd recommend inheriting Exception and creating your own exception class. I'd put a try-catch block inside your btnTest_Click() handler, and then I'd look to catch your custom exception class. That way, you won't lose the opportunity to detect any errors happening inside your myFunc() function.
I usually setup an error handling system. Here's a simple way, but this can be wrapped up into a base class. I can show you that if you need.
List<string> _errors;
void init()
{
_errors = new List<string>();
}
protected void Page_Load(object sender, EventArgs e)
{
init();
}
btnTest_Click(object sender, EventArgs e)
{
...
var result = myFunc(...);
if (result)
{...}
else
{
if (_errors.Count > 0)
{
var sb = new StringBuilder("<ul>");
foreach (string err in _errors)
{
sb.AppendLine(string.Format("<li>{0}</li>", err));
}
sb.AppendLine("</ul>");
lblStatus.Text=sb.ToString();//Make this a Literal
}
}
}
private bool myFunc(...)
{
var result = true;
try
{
...
...
}
catch (Exception ex)
{
result = false;
_errors.Add(ex.Message);
}
return result;
}
I've been wrapping all the code that invoke WCF calls within an using statement in a thought that the object will be disposed properly. When I'm googling for an exception "Http service located at .. is too busy" I found this link http://msdn.microsoft.com/en-us/library/aa355056.aspx that says should not use using statement in typed proxies. Is that really true? I think I got a big code change (sigh). Is this problem comes only in typed proxies?
Sample code:
private ServiceClient proxy;
using(proxy = new ServiceClient("ConfigName", "http://serviceaddress//service.svc")){
string result = proxy.Method();
}
The core of the problem is: at the end of your using block (which generally is a very good idea to have!), the WCF proxy will be disposed. However, during disposing of the WCF proxy, exceptions can occur - and those will cause the app to misbehave. Since this is done implicitly at the end of the using block, you might not even really see where the error occurs.
So typically, Microsoft recommends a pattern something like this:
private ServiceClient proxy;
try
{
proxy = new ServiceClient("ConfigName", "http://serviceaddress//service.svc");
string result = proxy.Method();
proxy.Close();
}
catch (CommunicationException e)
{
// possibly log error, possibly clean up
proxy.Abort();
}
catch (TimeoutException e)
{
// possibly log error, possibly clean up
proxy.Abort();
}
catch (Exception e)
{
// possibly log error, possibly clean up
proxy.Abort();
throw;
}
You need to call the proxy.Close() method explicitly and be prepared to handle any exceptions that might occur from that call, too.
Wrap the proxy operation and instantiation calls up in a class implementing IDisposable. When disposing, check the state property of the proxy and tidy up the channel before closing.
public void Dispose()
{
if (this.MyProxy != null && this.MyProxy.State == CommunicationState.Faulted)
{
this.MyProxy.Abort();
this.MyProxy.Close();
this.MyProxy = null;
}
// ...more tidyup conditions here
}
I like the approach from the comment from "Eric" on this blog (which is similar to another article: http://redcango.blogspot.com/2009/11/using-using-statement-with-wcf-proxy.htm):
"Personally, I like to create my own partial class for the client and override the Dispose() method. This allows me to use the ‘using’ block as I normally would.
public partial class SomeWCFServiceClient : IDisposable
{
void IDisposable.Dispose()
{
if (this.State == CommunicationState.Faulted)
{
this.Abort();
}
else
{
this.Close();
}
}
}
In Python, there is this useful exception handling code:
try:
# Code that could raise an exception
except Exception:
# Exception handling
else:
# Code to execute if the try block DID NOT fail
I think it's useful to be able to separate the code that could raise and exception from your normal code. In Python, this was possible as shown above, however I can't find anything like it in C#.
Assuming the feature or one like it doesn't exist, is it standard practice to put normal code in the try block or after the catch block?
The reason I ask is because I have the following code:
if (!IsReadOnly)
{
T newobj;
try
{
newobj = DataPortal.Update<T>(this);
List<string> keys = new List<string>(BasicProperties.Keys);
foreach (string key in keys)
{
BasicProperties[key] = newobj.BasicProperties[key];
}
}
catch (DataPortalException)
{
// TODO: Implement DataPortal.Update<T>() recovery mechanism
}
}
Which requires the normal code to be in the try block because otherwise if an exception was raised and subsequently handled, newobj would be unassigned, but it feels quite unnatural to have this much code in the try block which is unrelated to the DataPortalException. What to do?
Thanks
I would prefer to see the rest of the code outside the try/catch so it is clear where the exception you are trying to catch is coming from and that you don't accidentally catch an exception that you weren't trying to catch.
I think the closest equivalent to the Python try/catch/else is to use a local boolean variable to remember whether or not an exception was thrown.
bool success;
try
{
foo();
success = true;
}
catch (MyException)
{
recover();
success = false;
}
if (success)
{
bar();
}
But if you are doing this, I'd ask why you don't either fully recover from the exception so that you can continue as if there had been success, or else fully abort by returning an error code or even just letting the exception propagate to the caller.
Barbaric solution: create an Else class derived from Exception, throw an instance of it at the end of the try block, and use catch (Else) {...} to handle the other stuff.
I feel so dirty.
This will might get downvoted but doesn't c# have goto(note I have almost no c# knowledge so I have no idea if this works).
what about something like
try
{
...
}
catch(Exception ex)
{
...
goto Jump_past_tryelse
}
...//Code to execute if the try block DID NOT fail
Jump_past_tryelse:
...
C# does not have such a concept, so you are just left with three options,
put the else code inside the try.
put the else code outside the try catch block, use a local variable to indicate success or failure, and an if block around your else code.
put the else code in the finally block, use a local variable to indicate success or failure, and an if block arount you else code.
Allow me to repeat an idea from a similar StackOverflow question. You cannot do this directly, but you can write a method that encapsulates the behavior you need. Look at the original question to see how to implement the method (if you're not familiar with lambda expressions and Func delegates). The usage could look like this:
TryExceptRaise(() => {
// code that can throw exception
}, (Exception e) => {
// code to run in case of an exception
return (...);
}, () => {
// code to run if there is no exception
return (...);
});
Just put your "else" block before the catch. Then, it will only execute if code execution reaches that point:
try
{
fee();
fi();
foe();
fum();
/// put your "else" stuff here.
/// It will only be executed if fee-fi-foe-fum did not fail.
}
catch(Exception e)
{
// handle exception
}
Given that, I fail to see the use of try..catch...else unless there's something vital missing from the OP's description.
With C# version 7, you could use local functions to emulate this behaviour:
Example 1: (since C# version 7)
void Main()
{
void checkedCode()
{
try
{
foo();
}
catch (Exception ex)
{
recover();
return;
}
// ElseCode here
}
checkedCode();
}
If you prefer lambda syntax, you could also declare a run method
void Run(Action r) { r(); }
which only needs to be there once in your code, and then use the pattern for anonymous methods as follows
Example 2: (older C# versions and C# version 7)
Run(() => {
try
{
foo();
}
catch (Exception)
{
recover();
return;
}
// ElseCode here
});
whereever you need to enclose code in a safe context.
Try it in DotNetFiddle
Notes:
In both examples a function context is created so that we can use return; to exit on error.
You can find a similar pattern like the one used in Example 2 in JavaScript: Self-invoking anonymous functions (e.g. JQuery uses them). Because in C# you cannot self-invoke, the helper method Run is used.
Since Run does not have to be a local function, Example 2 works with older C# versions as well
You could do something like this:
if (!IsReadOnly)
{
T newobj = null;
try
{
newobj = DataPortal.Update<T>(this);
}
catch (DataPortalException)
{
// TODO: Implement DataPortal.Update<T>() recovery mechanism
}
if (newobj != null)
{
List<string> keys = new List<string>(BasicProperties.Keys);
foreach (string key in keys)
{
BasicProperties[key] = newobj.BasicProperties[key];
}
}
}
that would be the empty statement like hits
try
{
somethingThatCanThrow();
}
catch(Exception ex)
{
LogException(ex);
return;
}
ContinueFlow();
if (!IsReadOnly)
{
T newobj;
bool Done;
try
{
newobj = DataPortal.Update<T>(this);
List<string> keys = new List<string>(BasicProperties.Keys);
foreach (string key in keys)
{
BasicProperties[key] = newobj.BasicProperties[key];
}
Done = true;
}
catch (DataPortalException)
{
// TODO: Implement DataPortal.Update<T>() recovery mechanism
Done = false;
}
finally
{
if (newobj != null && Done == false)
{
List<string> keys = new List<string>(BasicProperties.Keys);
foreach (string key in keys)
{
BasicProperties[key] = newobj.BasicProperties[key];
}
}
}
}