I have this strange situation where I have an Outlook VSTO add-in written in c# targeting Outlook 2007 and 2010. The add-in works fine in 2007 environment. It also works fine in debug mode with Outlook 2010 in Visual Studio (2010) when I press start. However, once I deploy to UAT one of the functions doesn't get evaluated at all.
One of the functions is
private static bool HTTPTransmitEmailItem(string username, string email_file_name)
{
// DEBUG
Utils.LogDebug("Got into HTTPTransmitEmailItem");
try
{
Stopwatch timer = new Stopwatch();
timer.Start();
try
{
Utils.LogDebug("Msg saved as : " + full_file_name_and_path);
if (HTTPPostDataToEP(username, temp_path, email_file_name))
{
File.Delete(full_file_name_and_path);
return true;
}
else
{
Utils.LogWarn("Trans Fail, Storing for later sending. " + email_file_name);
//if need start resend timer
TransmitFailed();
}
}
catch (Exception ex)
{
Utils.HandleException("OFE HHTP Ex", ex);
TransmitFailed();
}
timer.Stop();
Utils.LogDebug("Email File Thread took " + timer.ElapsedMilliseconds.ToString() + "(ms)");
}
catch (Exception ex)
{
}
return false;
}
The culprit is the part:
if (HTTPPostDataToEP(username, temp_path, email_file_name))
{
File.Delete(full_file_name_and_path);
return true;
}
else
{
Utils.LogWarn("Trans Fail, Storing for later sending. " + email_file_name);
//if need start resend timer
TransmitFailed();
}
The application never enters the method HTTPPostDataToEP... The method definition is
private static bool HTTPPostDataToEP(string username, string path, string name)
{
// DEBUG
Utils.LogDebug("Got into HTTPPostDataToEP");
try
{
var content = new MultipartFormDataContent();
content.Add(new StringContent(username), "userAddress");
content.Add(new StreamContent(File.Open(path + name, FileMode.Open)), "msg", name);
// DEBUG
Utils.LogDebug("In Line 174 in OutlookTransmitRaw");
var client = new HttpClient();
HttpResponseMessage result = client.PostAsync(Utils.configEndPoint, content).Result;
// DEBUG
Utils.LogDebug("In Line 178 in OutlookTransmitRaw. Result is " + result);
if (result.IsSuccessStatusCode)
Utils.LogDebug("Msg Transmit Response : " + result.ToString());
else
Utils.LogInfo("Msg Fail Transmit Response: " + result.ToString());
return result.IsSuccessStatusCode;
}
catch (Exception ex)
{
throw new Exception("Failed to dispatch email to API. Caused by ", ex);
}
}
The application doesn't raise any exception. It simply walks pass that if block and executes Utils.LogDebug("Email File Thread took " + timer.ElapsedMilliseconds.ToString() + "(ms)"); This only happens when I publish the project and install it using set.exe file. In debug mode it works as expected...
The empty catch block would explain your problem: an exception is raised and you simply ignore that and happily carry on.
I could imaging something going wrong with file permissions after you deploy your solution, for instance. But whatever goes wrong gets swallowed up and you'll never hear about it...
Either throw from that catch block, or log something before you throw, but blindly ignoring exceptions like this is never a good idea. Something goes wrong, you get an exception with information, and you refuse to look at it.
Wrong:
catch (Exception ex)
{
}
Weird and useless:
catch (Exception ex)
{
throw;
}
Often useful:
catch (Exception ex)
{
Logger.Log(ex);
throw;
}
Related
I'm building an internal tool using Blazor WASM and dotnet6, which makes calls to external APIs.
Minimalistic example in Xunit - but imagine this is running from a Blazor client
[Xunit.Theory]
[InlineData("http://www.brokenexample.com/", "blocked for mixed-content")]
[InlineData("https://www.brokenexample.com/", "ERR_NAME_NOT_RESOLVED")]
[InlineData("https://www.api.with.cors.com/", "CORS Error")]
public async Task CanGetErrorMessage(string url, string expectedError)
{
try
{
var httpClient = new HttpClient();
var httpResponseMessage = await httpClient.GetAsync(url);
}
catch (Exception e)
{
var innerError = e.Message; // somehow find the inner error
Assert.Equal(innerError, expectedError);
}
}
Screenshot of "blocked for mixed content" in chrome network tab:
Screenshot of ERR_NAME_NOT_RESOLVED in chrome network tab:
Screenshot of CORS Error in chrome network tab:
However, my e.Message is always
"TypeError: Failed to fetch"
And the inner exception is always
System.Runtime.InteropServices.JavaScript.JSException
With the same error message, and no further inner exception
So I'm guessing Blazor is Interopping with Javascript, which throws an exception at it - Maybe the Interop/Proxy client is catching it and just returning "TypeError: Failed to fetch"
Somehow my (chrome) browser is able to distinguish between different kind of connection errors, but the "real" exception doesn't seems to appear anywhere in my exception stack.
Sometimes there's an Http-Statuscode that is somewhat useful, but anything that fails pre-flight like CORS or connection refused seems all the same
The purpose of this tool is that a user can input their URL during runtime and test the connection, so I can't really predetermine what will happen, and if the connection will work.
It's an internal tool, so I'd like to be able to tell my end-user something like "This url didn't work because of CORS, you can fix that by downloading a chrome extension to disable cors, etc etc. And more in detailed explanation why a certain url doesn't work, and assist them into getting it to work
Any way to get the status information as shown in these screenshots?
There's No Exception as its Chrome
It'd be nice if there was an exception with this detail, unfortunately none out of-the-box catch the detail (I've tried).
catch (WebException exc)
{
Console.WriteLine("Network Error: " + exc.Message + "\nStatus code: " + exc.Status);
}
catch (ProtocolViolationException exc)
{
Console.WriteLine("Protocol Error: " + exc.Message);
}
catch (UriFormatException exc)
{
Console.WriteLine("URI Format Error: " + exc.Message);
}
catch (NotSupportedException exc)
{
Console.WriteLine("Unknown Protocol: " + exc.Message);
}
catch (IOException exc)
{
Console.WriteLine("I/O Error: " + exc.Message);
}
catch (System.Security.SecurityException exc)
{
Console.WriteLine("Security Exception: " + exc.Message);
}
catch (InvalidOperationException exc)
{
Console.WriteLine("Invalid Operation: " + exc.Message);
}
catch (HttpRequestException exc)
{
Console.WriteLine("Invalid Operation: " + exc.Message);
}
catch (Exception exc)
{
Console.WriteLine("Invalid Operation: " + exc.Message);
}
Using Selenium4 to get Chrome Network & etc tabs
Fortunately with the latest release of Selenium 4 there is a way and that's using Chrome to catch it. Read more: https://www.selenium.dev/documentation/webdriver/bidirectional/chrome_devtools/
and/or this article that covers the technology with a previous version: https://rahulshettyacademy.com/blog/index.php/2021/11/04/selenium-4-key-feature-network-interception/
You can download the driver here (that aligns with your version of Chrome): http://chromedriver.storage.googleapis.com/index.html
Extract the ChromeDriver.exe and copy it to the Project\bin\Debug\net6.0 folder
Add Nuget Package Selenium.WebDriver 4.1 (or above).
Here is the code which I modified from the samples in Selenium4's documentation: https://www.selenium.dev/documentation/webdriver/bidirectional/chrome_devtools/
using System.Net;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.DevTools;
// We must use a version-specific set of domains
using OpenQA.Selenium.DevTools.V94.Performance;
var url = "https://www.brokenexample.com/";
IWebDriver driver = new ChromeDriver();
IDevTools devTools = driver as IDevTools;
DevToolsSession session = devTools.GetDevToolsSession();
//await session.SendCommand<EnableCommandSettings>(new EnableCommandSettings());
var metricsResponse =
await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
new GetMetricsCommandSettings());
try
{
driver.Navigate().GoToUrl(url);
driver.Quit();
}
catch (Exception ex)
{
var innerError = ex.Message;
}
Selenium4 breaking changes
A lot of examples you find online were written with the Beta version, like this one: https://dotjord.wordpress.com/2020/09/13/how-to-capture-network-activity-with-selenium-4-in-asp-net-core-3-1/
Beta (old code):
IDevTools devTools = driver as IDevTools;
DevToolsSession session = devTools.CreateDevToolsSession();
session.Network.ResponseReceived += ResponseReceivedHandler;
session.Network.Enable(new EnableCommandSettings());
driver.Navigate().GoToUrl(url);
public void ResponseReceivedHandler(object sender, ResponseReceivedEventArgs e)
{
System.Diagnostics.Debug.WriteLine($"Status: { e.Response.Status } : {e.Response.StatusText} | File: { e.Response.MimeType } | Url: { e.Response.Url }");
}
Alpha (working code):
using DevToolsSessionDomains = OpenQA.Selenium.DevTools.V96.DevToolsSessionDomains;
var driver = new ChromeDriver();
var devTools = (IDevTools)driver;
IDevToolsSession session = devTools.GetDevToolsSession();
var domains = session.GetVersionSpecificDomains<DevToolsSessionDomains>();
domains.Network.ResponseReceived += ResponseReceivedHandler;
await domains.Network.Enable(new OpenQA.Selenium.DevTools.V96.Network.EnableCommandSettings());
driver.Navigate().GoToUrl(url);
void ResponseReceivedHandler(object sender, ResponseReceivedEventArgs e)
{
System.Diagnostics.Debug.WriteLine($"Status: { e.Response.Status } : {e.Response.StatusText} | File: { e.Response.MimeType } | Url: { e.Response.Url }");
}
I have a code segment that is responsible for orchestrating the execution of a few modules and it is very sensitive to errors - I want to make sure I log and alert about every exception that occurs.
Right now I have something like this:
try
{
ModuleAResult aResult = ModuleA.DoSomethingA();
}
catch (Exception ex)
{
string errorMessage = string.Format("Module A failed doing it's thing. Specific exception: {0}", ex.Message);
// Log exception, send alerts, etc.
}
try
{
ModuleBResult bResult = ModuleB.DoSomethingB();
}
catch (Exception ex)
{
string errorMessage = string.Format("Module B failed doing it's thing. Specific exception: {0}", ex.Message);
// Log exception, send alerts, etc.
}
// etc for other modules.
It looks to me that the multiple try-catch is making this segment less readable. Is it indeed the right thing to do?
Yes, it's the right thing.
But you should have the performance in in mind, maybe it's better to put all method calls in one try/catch and add stack trace and error information in the exception in the methiod itself.
public void ModuleA.DoSomethingA()
{
throw new Exception("Error in module A");
}
try
{
ModuleAResult aResult = ModuleA.DoSomethingA();
ModuleBResult bResult = ModuleB.DoSomethingB();
}
catch (Exception ex)
{
// get information about exception in the error message
}
You did well.
This way, you can process the error after each module. If you want to run it all and then do error handling, consider this alternative:
try
{
ModuleAResult aResult = ModuleA.DoSomethingA();
ModuleBResult bResult = ModuleB.DoSomethingB();
}
catch(ModuleAException ex)
{
// handle specific error
}
catch(ModuleBException ex)
{
// handle other specific error
}
catch (Exception ex)
{
// handle all other errors, do logging, etc.
}
i think that depends on the approach that you want to follow.
It seems like you error messsages are different for each module that raises exception so i guess the approach that you followed is right.
you could have put the whole thing in a big try - catch block then in that case you will not know which module caused the exception as a generic excpetion gets printed.
try
{
ModuleAResult aResult = ModuleA.DoSomethingA();
ModuleBResult bResult = ModuleB.DoSomethingB();
}
catch (Exception ex)
{
string errorMessage = string.Format("Either Module A or B failed", ex.Message);
// Log exception, send alerts, etc.
}
So if you want your exception handling to not be cleaner use the above code.
Otherwise what you followed is absolutely fine.
I'm developing a simple test tool to verify how many HASH(SHA1) the customer server can elaborate in 1 second.
The attached sample use muti-threading to start and stop a timer that counts executed HASH.
The HASHes are sequential.
The application works well in Visual Studio, but if I run it outside the VS environment it crashes.
The problem is on increment() function in "using" section. If I comment it, everything works well!
static void increment()
{
try
{
using (SHA1 sha = new SHA1CryptoServiceProvider())
{
byte[] result;
byte[] data = new byte[20];
new Random().NextBytes(data);
result = sha.ComputeHash(data);
}
Interlocked.Increment(ref safeInstanceCount);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
The code used to start and stop the time is the following:
bool stop;
static void Main()
{
try {
TimerQueueTimer qt;
qt = new TimerQueueTimer();
TimerQueueTimer.WaitOrTimerDelegate CallbackDelete = new TimerQueueTimer.WaitOrTimerDelegate(QueueTimerCallback);
uint dueTime = uint.Parse(textBox1.Text); // string "60000" = 1 min
uint period = 0;
qt.Create(dueTime, period, CallbackDelete);
while (!stop)
{
// Thread thread = new Thread(new ThreadStart(increment));
// thread.IsBackground = true;
// thread.Start();
increment();
}
stop = false;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
private void QueueTimerCallback(IntPtr pWhat, bool success)
{
try
{
stop = true;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
How can I understand where is the error?
=
The application crashes without any exception.
I try to catch it, without success, it happened after 60 sec. (Maybe QueueTimerCallback is called?)
The application does not generate any error trace and it DOES not crash running under Visual Studio!
When it crashes it does not generate any stack trace, just a pop-up crash window giving in detail the "StackHash_xxxxx" error
Nothing to do! I've try to use Console.Read (it's a Windows app not console) but I cannot see anything. Here is the error shown! https://picasaweb.google.com/lh/photo/iHsBhRSy-DNTYVo4CpoeA9MTjNZETYmyPJy0liipFm0?feat=directlink
Your program is likely throwing an exception, and it's getting written to the console, but you don't have anything from stopping the console from closing immediately after the message is written.
Add a Console.ReadKey(); after your try/catch block.
Am just wondering how to workaround my scenario,here is my code
try
{
bool b;
foreach (string file in files)
{
#region donloadfiles
if (b = file.Contains(story))
{
try
{
logger.Info("calling xml creation Method");
baseMeta(story, XML);
logger.Info("XML created");
}
catch (Exception ex)
{ logger.Error(ex.Message); throw; }
logger.Info("calling Download Method");
Download(file, story, xml, program);
logger.Info("Download Method processed successfully");
}
#endregion
}
}
catch (Exception ex)
{ logger.Error(ex.Message); throw; }
As promised,here is my main method contains try catch block
try
{
//update the status here in DB
Status = "Closed";
Update(status);
}
catch (Exception ex)
{
Status = "Failed";
Update(status);
break;
}
i have directory "for eg:C:\" my getlist method grab all the record and pass it to my foreach loop "foreach (string file in files)" then i have a condition
if (b = file.Contains(story)) to check any of my file have the name "story" then do some logic inside.this thing works good.
Now what am trying to do is,if none of the files are matching then i have to forcefully call the catch and throw to the main catch,am doing some logic update in my main catch.
Someone please advice me how can i workaround this scenario.
Thanks in advance
what am trying to do is,if none of the files are matching then i have
to forcefully call the catch and throw to the main catch,am doing some
logic update in my main catch.
bool anyMatch = false;
foreach (.....)
{
if (b = file.Contains(story))
anyMatch = true;
}
if(!anyMatch)
throw ... //this will be caught by main catch
Keep a bool variable outside foreach loop. Set it to true if any file matches. if it is false at the end of foreach loop throw exception
Usher, using exceptions to manage process flow is a BAD idea!
Exceptions are there to manage errors, and not to handle expected conditions in your code's execution.
A much better way (in the long run:trust me on this) would be to return some value out of your method when none of the files match instead of throwing an exception.
Something like:
#region donloadfiles
if (b = file.Contains(story))
{
try
{
logger.Info("calling xml creation Method");
baseMeta(story, XML);
logger.Info("XML created");
}
catch (Exception ex)
{ logger.Error(ex.Message); throw; }
logger.Info("calling Download Method");
Download(file, story, xml, program);
logger.Info("Download Method processed successfully");
}
else return "no matches found";
#endregion
and handle the process from there once you've gotten the "no matches found" value in the place that called this method.
Hello I would like to write my userdefined exception to a log file.
So Instead of throwing my exception I would like to log that message into a txt file.
The constructor for my exception looks like this:
public OpenFileException(string pathToOpen, Exception innerexception)
: base("Couldn't find the path: " + pathToOpen, innerexception)
{
this.pathToOpen = pathToOpen;
}
This is how I am logging my exception at the moment:
try
{
string data = Read(txtLocation.Text);
txtInfo.Text = data;
}
catch (Exception ex)
{
WriteLog("[" + DateTime.Now + "]" + " " + ex.Message);
MessageBox.Show(" ");
throw new OpenFileException(txtLocation.Text, ex);
}
So what I'm asking is. How can I log my string "Couldn't find the path: " to a txt file?
I would normally catch and log the user defined exception outside the normal try/catch
try {
try {
string data = Read(txtLocation.Text);
txtInfo.Text = data;
} catch (Exception ex) {
throw new OpenFileException(txtLocation.Text, ex);
}
....
} catch(OpenFileException ex) {
WriteLog("[" + DateTime.Now + "]" + " " + ex.Message);
MessageBox.Show(" ");
} catch(Exception ex) {
WriteLog("[" + DateTime.Now + "]" + " " + ex.Message);
MessageBox.Show(" ");
}
You are creating a user defined exception so you can handle it differently
It looks a bit overkilling, why don't you use Log4Net and let it write files or send you emails depending on its configuration in the app.config?
basically you get all what you can want out of the box with no effort, then you can concentrate on what matters the most.
even if you decide to keep your current logic, I would anyway create a Logger class which does everything instead of having to specify DateTime.Now and other magic in every single catch block of your application.
You can use, instead of reinvent the wheel, log4net http://logging.apache.org/log4net/ or NLog http://nlog-project.org/wiki/Documentation both worth the effort to learn and use even in simple applications.
You need to find a way to get your exception thrown when a file is not found.
I don't think this is a good idea, because .NET already throws the FileNotFoundException when a file is not found. You should catch that and log the message that way.
try
{
string data = Read(txtLocation.Text);
txtInfo.Text = data;
}
catch (FileNotFoundException ex)
{
string log = String.Format("[{0}] Couldn't find the path: {1}"
, DateTime.Now
, ex.FileName);
WriteLog(log);
}
Don't make a new exception type when one already exists.
(Forgive the idiosyncrasies in my formatting)
From Framework Desing Guidelines:
Do override ToString when your exception provides extra properties.
Then you can just call log.Error(exception) and it will be logged just the way you wrote ToString() without extra actions.