After scenario Cleanup in Specflow - try catch finally - c#

I am try to clean up the scenario by capturing screenshots
The problem I face is when I try to see how many times "try catch finally" is executed..it's executed nearly 20 times after initial try-finally-it goes directly to catch
Here is my code
[AfterScenario]
public void CleanUp()
{
int aaa = 0;
try
{
if (ScenarioContext.Current.TestError != null)
{
//Taking screenshot
}
Console.WriteLine("try");
}
catch
{
Console.WriteLine("Catch");
if (Browser != null)
{
Browser.Dispose();
Browser = null;
}
return;
}
finally
{
Console.WriteLine("finally");
if (Browser != null)
{
Browser.Dispose();
Browser = null;
Console.WriteLine("finallya");
}
}
return;
}
try
finally
after this why it goes to Catch again? when I am doing some thing wrong here?

Related

Received "" Error when running the below c# code

I get an error when running the following code. When the program comes to the workbook2 != null line of code, it crashes.
Error:
System.Runtime.InteropServices.COMException (0x80010108): The object invoked has disconnected from its clients. (Exception from HRESULT: 0x80010108 (RPC_E_DISCONNECTED))
at Microsoft.Office.Interop.Excel._Workbook.Close(Object SaveChanges, Object Filename, Object RouteWorkbook)
Code:
public void CompleteAuto()
{
if (workbook1 != null)
{
MessageBox.Show("workbook1 is closed");
workbook1.Close(false);
}
if (workbook2 != null)
{
MessageBox.Show("workbook2is closed");
workbook2.Close(false);
}
if (workbook3 != null)
{
MessageBox.Show("workbook3 is closed");
workbook3.Close(false);
}
if (workbook4 != null)
{
MessageBox.Show("workbook4 is closed");
workbook4.Close(false);
}
if (workbook5 != null)
{
MessageBox.Show("workbook5 is closed");
workbook5.Close(false);
}
if (workbook6 != null)
{
MessageBox.Show("workbook6 is closed");
workbook6.Close(false);
}
if (workbook7 != null)
{
MessageBox.Show("workbook7 is closed");
workbook7.Close(false);
}
if (workbook8 != null)
{
MessageBox.Show("workbook8 is closed");
workbook8.Close(false);
}
if (stepByStep == false)
{
MessageBox.Show("Step by Step done!");
loadingForm.Hide();
}
MessageBox.Show("Output successful!");
this.Close();
}
I am new to c# so I don't know if the above code is right or wrong. I just want to multiple if to check if the workbooks had been open. If yes then closed them, if no then the program keep running.
Could anyone help me? Thanks.
Just a guess, as your example is incomplete...
When you close the Workbook, you are not setting it to null.
Add
Workbook1= null;
after Workbook1.Close.
Same for all the other closures.
You need to make a function, which checks if your workbook is opened.
If it is not, it throws. It is not ideal, but it works.
public static IsOpened(Excel.Application currentApp, string workbook)
{
try
{
var item = currentApp.WorkBooks.get_item(workbook);
return true;
}
catch
{
return false;
}
}
From Bob's answer, I successfully solved my question.
Here is my code:
if (workbook1 != null)
{
workbook1.Close(false);
workbook1 = null;
}
And guess what, it works!!!!

The inner-most exception in c#

Is there a way to get the inner-most exception without using :
while (e.InnerException != null) e = e.InnerException;
I'm looking for something like e.MostInnerException.
To extend on Hans Kesting's comment, an extension method might come in handy:
public static Exception GetInnerMostException(this Exception e)
{
if (e == null)
return null;
while (e.InnerException != null)
e = e.InnerException;
return e;
}
Here is another answer that differs a bit: you can create an enumerator.
With
public static IEnumerable<Exception> EnumerateInnerExceptions(this Exception ex)
{
while (ex.InnerException != null)
{
yield return ex.InnerException;
ex = ex.InnerException;
}
}
You can do
try
{
throw new Exception("1", new Exception("2", new Exception("3", new Exception("4"))));
}
catch (Exception ex)
{
foreach (var ie in ex.EnumerateInnerExceptions())
{
Console.WriteLine(ie.Message);
}
}
So, technically, you are not longer using a while loop a visible way :)

WebException not caught in try/catch

I saw several posts with similar problem but no solution works :/
I debug a windows service by using a console application. It executes tasks on website and must be able to collect http code status for create logs. As you can see, sensitive code is in try/catch.
When I debug (F5), I have a WebException that is not caught. When I run (CTRL + F5), the exception's message is write in my console and stops my program.
This is my code :
public partial class Schedulor : ServiceBase
{
void RunTasks()
{
schedulor.Start();
List<Task> task = new List<Task>();
foreach (TaskPlanner tp in listTp)
{
if (tp.CountDown == 0 && tp.IsRunning == false)
{
// Initialisation lors de GetTasks()
tp.IsRunning = true;
try
{
task.Add(Task.Factory.StartNew(() => tr = tp.ExecuteBot.Execute())); // WEBEXECPTION HERE (cannot find 404)
}
catch (Exception e)
{
if (e is WebException)
{
// treatment
}
}
}
}
Task.WaitAll(task.ToArray());
CreateLogs();
}
}
public class Bot : IBot
{
public TaskResult Execute()
{
TaskResult tr = new TaskResult();
int codeResponse, timeout;
string credentials;
try
{
WebRequest wrSettings = WebRequest.Create(settings.Url);
// treatment
}
catch (Exception e)
{
//Console.WriteLine(e.Message);
if (e is WebException)
{
var code = ((HttpWebResponse)((WebException)e).Response).StatusCode;
if ((int)code != settings.HttpResponse)
{
tr.MyResult = TaskResult.Result.nok;
goto next;
}
else tr.MyResult = TaskResult.Result.ok;
}
}
next:
return tr;
}
}
I do not understand why my catch does not work. I need to treat this information because the task can test if a website return 404 or anything else.
Thanks in advance
EDIT : -----------
I reduce code as it requests because deleted code does not the real problem
You should catch that exception in task. Add another method, and create your tasks similar to:
task.Add(Task.Factory.StartNew(() => Process(tp)));
void Process(TaskPlanner tp)
{
try
{
tp.ExecuteBot.Execute();
}
catch (WebException wex)
{
}
}

How to go from one exception handler to another?

The best way to explain my question is with the following pseudo-code:
try
{
//Do work
}
catch (SqlException ex)
{
if (ex.Number == -2)
{
debugLogSQLTimeout(ex);
}
else
{
//How to go to 'Exception' handler?
}
}
catch (Exception ex)
{
debugLogGeneralException(ex);
}
Exception ex = null;
try
{
//Do work
}
catch (SqlException sqlEx)
{
ex = sqlEx;
if (ex.Number == -2)
{
//..
}
else
{
//..
}
}
catch (Exception generalEx)
{
ex = generalEx;
}
finally()
{
if (ex != null) debugLogGeneralException(ex);
}
The first catch clause that matches is the only one that can possibly run on the same try block.
The best way I can think of to do what you're attempting is to include casts and conditionals in the more general type:
try
{
//Do work
}
catch (Exception ex)
{
var sqlEx = ex as SqlException;
if (sqlEx != null && sqlEx.Number == -2)
{
debugLogSQLTimeout(ex);
}
else
{
debugLogGeneralException(ex);
}
}
If you find yourself writing this over and over again throughout your data layer, at least take the time to encapsulate it in a method.
I do not believe there is any way to do this as the catch blocks are in different scopes. There's no way to re-throw without exiting the try block and no way to 'call' the final catch block because it's only triggered during an exception.
I would suggest the same as roman m above and just make the same call. Otherwise you have to do something really bad. Like the below crazy code which you should never ever use but i included because it does something like what you want.
In general I think what you are doing is controlling normal flow via exceptions which isn't recommended. If you are trying to track for timeouts, you should probably just handle that another way.
Note that you could do something like the code below with the insanity of a goto statement, but i included it so no one can forget what a bad idea this is. =)
void Main()
{
Madness(new NotImplementedException("1")); //our 'special' case we handle
Madness(new NotImplementedException("2")); //our 'special' case we don't handle
Madness(new Exception("2")); //some other error
}
void Madness(Exception e){
Exception myGlobalError;
try
{
throw e;
}
catch (NotImplementedException ex)
{
if (ex.Message.Equals("1"))
{
Console.WriteLine("handle special error");
}
else
{
myGlobalError = ex;
Console.WriteLine("going to our crazy handler");
goto badidea;
}
}
catch (Exception ex)
{
myGlobalError = ex;
Console.WriteLine("going to our crazy handler");
goto badidea;
}
return;
badidea:
try{
throw myGlobalError;
}
catch (Exception ex)
{
Console.WriteLine("this is crazy!");
}
}
// Define other methods and classes here

Keep WCF Service Connected

How can I keep my WCF Service Client Connected with WinForm even if a Faulted State appened ?
Thanks.
Answer myself :)
You might subscribe to InnerChannel Events
svc.InnerChannel.Closed += InnerChannel_Error;
svc.InnerChannel.Closing += InnerChannel_Error;
svc.InnerChannel.Faulted += InnerChannel_Error;
Then Handle Exceptions and Recreate the Service Proxy
private void InnerChannel_Error(object sender, EventArgs e)
{
var svc = _entrepotService as EntrepotServiceProxy;
try
{
if (svc != null)
{
if (svc.State != CommunicationState.Faulted)
{
svc.Close();
}
else
{
svc.Abort();
}
}
}
catch (CommunicationException)
{
if (svc != null) svc.Abort();
}
catch (TimeoutException)
{
if (svc != null) svc.Abort();
}
catch
{
if (svc != null) svc.Abort();
throw;
}
_entrepotService = new EntrepotServiceProxy();
}
As far as I know, a faulted state is usually terminal to a WCF proxy. So no, I don't think so.

Categories

Resources