Console application not logging error with NLOG in AppDomain.CurrentDomain.UnhandledException - c#

The below code isn't logging to my database. Is it because the console application closes too soon and if so how can I prevent this?
private static ILogger _logger;
static void UnhandledExceptionTrapper(object sender, UnhandledExceptionEventArgs e)
{
_logger.Error((Exception)e.ExceptionObject);
}
private static void Main(string[] args)
{
var container = new Container();
_logger = container.GetInstance<ILogger>();
AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionTrapper;
throw new Exception("test");

You can call LogManager.Shutdown() before leaving your UnhandledExceptionTrapper method. This calls internally LogManager.Flush() which
Flush any pending log messages (in case of asynchronous targets) with the default timeout of 15 seconds.
see NSLog Flush documentation.
Additional Troubleshooting
In the debug console, error messages are displayed if, for example, SQL errors occur on the connection, but by default you do not see if you have an invalid configuration.
Since NLog offers extensive configuration options, it is easy to make a small configuration errors that results in no logging. A typical example would be an incorrect ConnectionString or DBProvider.
As an example, suppose you have configured an incorrect DBProvider.
You can e.g call
LogManager.GetCurrentClassLogger().Debug("test logging");
LogManager.Flush();
and it would just silently fail.
However, if you insert
LogManager.ThrowExceptions = true;
before the test log call, you will see appropriate messages in the debug console. For example, if you have an invalid DBProvider like Npgsql.NpgsqlConnection1, Npgsql (note the invalid 1 in it), you would see
Unhandled exception. NLog.NLogRuntimeException: Exception occurred in NLog
---> NLog.NLogRuntimeException: Target Database Target[nlog-db] failed to initialize.
---> System.TypeLoadException: Could not load type 'Npgsql.NpgsqlConnection1' from assembly 'Npgsql'.
which would give a clear indication of what went wrong.
More Diagnostics
To see even more diagnostics, you can add the following lines:
InternalLogger.LogToConsole = true;
InternalLogger.LogLevel = LogLevel.Trace;
Among other things, you can see when the connection is opened, what data is written and information about flushing, a small sample excerpt:
2022-03-11 08:47:56.8428 Trace DatabaseTarget(Name=nlog-db): Open connection.
2022-03-11 08:47:57.0275 Trace DatabaseTarget(Name=nlog-db): Executing Text: insert into "public"."log_table"(time_stamp,level,logger,message,stacktrace) values(CAST(#time_stamp AS timestamp),#level,#logger,#message,#stacktrace);
2022-03-11 08:47:57.0380 Trace DatabaseTarget: Parameter: '#time_stamp' = '2022-03-11T08:47:56.837' (String)
2022-03-11 08:47:57.0380 Trace DatabaseTarget: Parameter: '#level' = 'Debug' (String)
2022-03-11 08:47:57.0380 Trace DatabaseTarget: Parameter: '#logger' = 'ConsoleDBLog.Program' (String)
2022-03-11 08:47:57.0395 Trace DatabaseTarget: Parameter: '#message' = 'test logging' (String)
2022-03-11 08:47:57.0415 Trace DatabaseTarget: Parameter: '#stacktrace' = '' (String)
2022-03-11 08:47:57.1099 Trace DatabaseTarget(Name=nlog-db): Finished execution, result = 1
2022-03-11 08:47:57.1111 Trace DatabaseTarget(Name=nlog-db): Close connection (KeepConnection = false).
2022-03-11 08:47:57.1167 Debug LogFactory Flush with timeout=15 secs
Self-Contained Example
using System;
using NLog;
using NLog.Targets;
namespace ConsoleDBLog;
internal static class Program
{
private static ILogger? _logger;
static void UnhandledExceptionTrapper(object sender, UnhandledExceptionEventArgs e)
{
_logger?.Error((Exception?) e.ExceptionObject, "unhandled exception");
LogManager.Shutdown();
}
private static void Main()
{
SetupDB_NLOG();
_logger = LogManager.GetCurrentClassLogger();
AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionTrapper;
throw new Exception("test");
}
static void SetupDB_NLOG()
{
DatabaseTarget target = new DatabaseTarget();
target.Name = "nlog-db";
target.DBProvider = "Npgsql.NpgsqlConnection, Npgsql";
target.ConnectionString = "Server=127.0.0.1;Port=5432;User Id=stephan;Password=;Database=stephan;";
target.CommandText =
"insert into \"public\".\"log_table\"(time_stamp,level,logger,message,stacktrace) values(CAST(#time_stamp AS timestamp),#level,#logger,#message,#stacktrace);";
var param = new DatabaseParameterInfo
{
Name = "#time_stamp",
Layout = "${date:format=yyyy-MM-ddTHH\\:mm\\:ss.fff}"
};
target.Parameters.Add(param);
param = new DatabaseParameterInfo
{
Name = "#level",
Layout = "${level}"
};
target.Parameters.Add(param);
param = new DatabaseParameterInfo
{
Name = "#logger",
Layout = "${logger}"
};
target.Parameters.Add(param);
param = new DatabaseParameterInfo
{
Name = "#message",
Layout = "${message}"
};
target.Parameters.Add(param);
param = new DatabaseParameterInfo
{
Name = "#stacktrace",
Layout = "${exception:format=stacktrace}"
};
target.Parameters.Add(param);
NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Debug);
//Uncomment the following lines to see things that would silently fail and
//to get more diagnostic debug output about what is actually running.
// InternalLogger.LogToConsole = true;
// InternalLogger.LogLevel = LogLevel.Trace;
// LogManager.ThrowExceptions = true;
// LogManager.GetCurrentClassLogger().Debug("test logging");
// LogManager.Flush();
}
}
Which gives the followoing entries in the DB:

Related

Exception is thrown while reading the SQL Server Trace

I am trying to capture the queries via SQL Server trace using C# that are getting executed during my automation test run. When I run the below code ,I am getting the exception
'Failed to initialize object as reader.'
So In this case what can be done?
Source Code
class Program
{
static void Main(string[] args)
{
using (Impersonation user = new Impersonation("xxx", "xxx","xxx"))
{
ConnectionInfoBase conninfo = new SqlConnectionInfo();
((SqlConnectionInfo)conninfo).ServerName = "xxxxx";
((SqlConnectionInfo)conninfo).UseIntegratedSecurity = true;
TraceServer trace = new TraceServer();
trace.InitializeAsReader(conninfo, #"Standard.tdf");
for (int count = 0; count < 30; count++)
{
while (trace.Read())
{
Console.WriteLine(trace["TextData"]);
}
Thread.Sleep(1000);
}
}
}
}
Inner Exception
SqlTraceException: Failed to get SQL Tools directory path from InstAPI....
This exception was originally thrown at this call stack:
Microsoft.SqlServer.Management.Trace.TraceUtils.GetSqlToolsBinaryPath(string)
Microsoft.SqlServer.Management.Trace.TraceUtils.CreateInstance(string, string)
Microsoft.SqlServer.Management.Trace.TraceServer.InitializeAsReader(Microsoft.SqlServer.Management.Common.ConnectionInfoBase, string)

Dependency Resolution Exception

I am doing Unit Testing In my Project.When I try to unit test my method a browser pops up and suddenly gets stopped after that I get a long exception I pasted following.
How to fix this mess as I have no idea whats the cause?
Exception:
https://paste.ubuntu.com/24389202/
BrowseHost Class
public static class BrowserHost
{
public static readonly SelenoHost Instance = new SelenoHost();
public static readonly String RootUrl;
static BrowserHost()
{
Instance.Run("BankingSite", 1468);
RootUrl= Instance.Application.Browser.Url;
}
}
UnitTest Class
namespace BankingSite.FunctionalUITests
{
[TestFixture]
public class LoanApplicationTest
{
[Test]
public void ShouldAcceptLoanApplication()
{
BrowserHost.Instance
.Application.Browser
.Navigate()
.GoToUrl($#"{BrowserHost.RootUrl}\LoanApplication\Apply");
var firstNameBox = BrowserHost.Instance.Application
.Browser
.FindElement(By.Id("FirstName"));
firstNameBox.SendKeys("Gentry");
var lastNameBox = BrowserHost.Instance.
Application.
Browser.
FindElement(By.Id("LastName"));
lastNameBox.SendKeys("Smith");
var ageBox = BrowserHost.Instance
.Application
.Browser
.FindElement(By.Id("Age"));
ageBox.SendKeys("40");
var incomeBox = BrowserHost.Instance
.Application
.Browser
.FindElement(By.Id("AnnualIncome"));
incomeBox.SendKeys("9999999");
Thread.Sleep(10000);
var applyButton = BrowserHost.Instance
.Application
.Browser
.FindElement(By.Id("Applt"));
applyButton.Click();
Thread.Sleep(10000);
var acceptMessageText = BrowserHost.Instance
.Application
.Browser
.FindElement(By.Id("acceptMessage"));
Assert.That(acceptMessageText, Is.EqualTo("Congratulations Gentry - Your Application was accepted!"));
Thread.Sleep(10000);
}
}
Following is the Screen Shot of URL I am browsing directly.
Hard to tell from what you've provided, but there is a clue in the stack trace:
System.TypeInitializationException : The type initializer for 'BankingSite.FunctionalUITests.BrowserHost' threw an exception.
----> Autofac.Core.DependencyResolutionException : An exception was thrown while executing a resolve operation. See the InnerException for details. ---> Not a Number (See inner exception for details.)
----> System.InvalidOperationException : Not a Number
Check the constructor for BankingSite.FunctionalUITests.BrowserHost and see if you can find the line that is causing the error. Apparently it is expecting a numeric value but received something else instead.

unhandled exceptions at startup in my c# project

I am getting below Unhandled exception at the startup of my chatbot application in output window.
Exception thrown: 'System.UnauthorizedAccessException' in mscorlib.dll
Exception thrown: 'System.Globalization.CultureNotFoundException' in mscorlib.dll
Exception thrown: 'System.Security.SecurityException' in mscorlib.dll
Exception thrown: 'System.BadImageFormatException' in mscorlib.dll
Exception thrown: 'System.ArgumentNullException' in mscorlib.dll
Exception thrown: 'System.IO.FileNotFoundException' in mscorlib.dll
Exception thrown: 'System.IO.FileNotFoundException' in mscorlib.dll
I have something in my MessageController
public class MessagesController : ApiController
{
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
private static DocumentClient client;
// Retrieve the desired database id (name) from the configuration file
private static readonly string databaseId = ConfigurationManager.AppSettings["DatabaseId"];
// Retrieve the desired collection id (name) from the configuration file
private static readonly string collectionId = ConfigurationManager.AppSettings["CollectionId"];
// Retrieve the DocumentDB URI from the configuration file
private static readonly string endpointUrl = ConfigurationManager.AppSettings["EndpointUri"];
// Retrieve the DocumentDB Authorization Key from the configuration file
private static readonly string authorizationKey = ConfigurationManager.AppSettings["PrimaryKey"];
/// <summary>
/// POST: api/Messages
/// Receive a message from a user and reply to it
/// </summary>
public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
{
Trace.TraceInformation($"Type={activity.Type} Text={activity.Text}");
//disable the Application Insights and DocumentDb logging in local enviornment
#if (LOCAL)
Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.Active.DisableTelemetry = true;
#endif
#if (!LOCAL)
if (!String.IsNullOrEmpty(endpointUrl) && !String.IsNullOrEmpty(authorizationKey))
{
using (client = new DocumentClient(new Uri(endpointUrl), authorizationKey))
{
await CaptureConversationData(activity);
}
}
#endif
if (activity.Type == ActivityTypes.Message)
{
//await Microsoft.Bot.Builder.Dialogs.Conversation.SendAsync(activity, () => new ContactOneDialog());
//Implementation of typing indication
//ConnectorClient connector = new ConnectorClient(new System.Uri(activity.ServiceUrl));
//Activity isTypingReply = activity.CreateReply("Shuttlebot is typing...");
//isTypingReply.Type = ActivityTypes.Typing;
//await connector.Conversations.ReplyToActivityAsync(isTypingReply);
logger.Debug("The User's local timeStamp is: " + activity.LocalTimestamp + "and service timeStamp is: " + activity.Timestamp);
await Conversation.SendAsync(activity, () =>
new ExceptionHandlerDialog<object>(new ShuttleBusDialog(), displayException: true));
}
else
{
HandleSystemMessage(activity);
}
var response = Request.CreateResponse(System.Net.HttpStatusCode.OK);
return response;
}
}
It thrown at first line
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
here is the snapshot,
One weired thing is that if my project run from C:\Users\\chatbot\Mybot..
then these exception are not getting thrown even i have put the break exception setting in exception setting window.
but if I move the project to c:\Sandy\MyStuff\ChatbOt\MyBot it's started throwing all these exception since i have put the break exception setting in exception setting window.
I am seriously not able to understand what is the problem.
Try running your visual studio as administrator or running your application as administrator, and check that all the Dlls that your project depends on are there in the new path.

Using wait.until throws System.InvalidOperationException: No session ID specified

I have many test cases, where I need to wait until the page is loaded. I'm using explicit wait as the load times vary.
WebDriverWait _wait = new WebDriverWait(Drivers._driverInstance, new TimeSpan(0, 2, 0));
_wait.Until(D => D.Title);
It throws No session ID exception. I have a table that takes time to load in the page, so I tried using
_wait.Until(ExpectedConditions.ElementIsVisible(By.TagName("table")));
Even this throws the same error. The tests pass when I run each one individually and running all of them as suite raises this exception.
private static void InitialUpload(string filename)
{
SDDirectPage.filePath = filename;
SDDirectPage.filename = Path.GetFileNameWithoutExtension(SDDirectPage.filePath);
SDDirectPage.UploadButton.Click();
Drivers._driverInstance.SwitchTo();
SDDirectPage.FileReference = SDDirectPage.filename;
SDDirectPage.UploadTheFile();
//Check whether 404 occurred or the uploading file is smooth
if (Drivers._driverInstance.Title == "404 - File or directory not found.") //A bug at the moment, it uploads corrupted files most of the times.
{
Assert.Fail("404 error occurred. File might be corrupted or file mightnot be in the specified location..!");
return;
}
else
{
Drivers._driverInstance.SwitchTo().ParentFrame();
// SDDirectPage._wait.Until(D => D.Title);
SDDirectPage._wait.Until(ExpectedConditions.ElementIsVisible(By.TagName("table")));
Assert.AreEqual(SDDirectPage.filename + " - SmartDebit Front End Portal", Drivers._driverInstance.Title);
}
}
This is the function where I'm getting the exception. In some test cases, I have Assert.AreEqual, where I compare the titles. In those test cases, driver.Title raises the same error.
Here is the exception:
Test FullName: SDTestAutomation.SDDirectPage_Tests.FixInvalidRows_Search
Test Source: c:\Git\AutomationTest\automationtest\AutomationTest\SDTestAutomation\SDDirectPage_Tests.cs : line 249
Test Outcome: Failed
Test Duration: 0:02:19.2199494
Result Message:
Test method SDTestAutomation.SDDirectPage_Tests.FixInvalidRows_Search threw exception:
System.InvalidOperationException: No session ID specified
Result StackTrace:
at OpenQA.Selenium.Remote.RemoteWebDriver.UnpackAndThrowOnError(Response errorResponse)
at OpenQA.Selenium.Remote.RemoteWebDriver.Execute(String driverCommandToExecute, Dictionary`2 parameters)
at OpenQA.Selenium.Remote.RemoteWebDriver.FindElement(String mechanism, String value)
at OpenQA.Selenium.Remote.RemoteWebDriver.FindElementByTagName(String tagName)
at OpenQA.Selenium.By.<>c__DisplayClass1a.<TagName>b__18(ISearchContext context)
at OpenQA.Selenium.By.FindElement(ISearchContext context)
at OpenQA.Selenium.Remote.RemoteWebDriver.FindElement(By by)
at OpenQA.Selenium.Support.UI.ExpectedConditions.<>c__DisplayClass13.<ElementIsVisible>b__12(IWebDriver driver)
at OpenQA.Selenium.Support.UI.DefaultWait`1.Until[TResult](Func`2 condition)
at SDTestAutomation.SDDirectPage_Tests.InitialUpload(String filename) in c:\Git\AutomationTest\automationtest\AutomationTest\SDTestAutomation\SDDirectPage_Tests.cs:line 483
at SDTestAutomation.SDDirectPage_Tests.FixInvalidRows_Search() in c:\Git\AutomationTest\automationtest\AutomationTest\SDTestAutomation\SDDirectPage_Tests.cs:line 250
Here is the drivers class:
public class Drivers
{
static string path = #"C:\SmartDebit\SmartDebitTestAutomation\SmartDebitFramework\DriverResources\";
public static IWebDriver _driverInstance { get; set; }
public static void Initialize(string browser)
{
if (browser == "FF")
{
_driverInstance = new FirefoxDriver();
_driverInstance.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(5000));
}
if (browser == "IE")
{
_driverInstance = new InternetExplorerDriver(path);
_driverInstance.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(5000));
}
if (browser == "Chrome")
{
_driverInstance = new ChromeDriver(path);
_driverInstance.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(5000));
}
}
}
Code for initialising the browser instance:
[ClassInitialize]
public static void BrowserInstance(TestContext t)
{
loginPage = new LoginPage();
loginPage.Init("FF");
loginPage.Goto("url of the application");
Assert.AreEqual("Login Page", Drivers._driverInstance.Title, "Login page titles doesn't match");
}
[TestInitialize]
public void Init()
{
try
{
Login();
}
catch (Exception ex)
{
Console.WriteLine("Exception:" + ex);
Assert.Fail("ValidLogin() test failed in HomePage_Tests.cs");
loginPage.QuitBrowser();
}
}
private static void Login()
{
loginPage.LoginName = "username";
loginPage.Password = "password";
loginPage.LoginButton();
SDDirectPage._wait.Until(d=>Drivers._driverInstance.Title);
Assert.AreEqual("Home Page - Front End Portal", Drivers._driverInstance.Title, "Home page title doesn't match");
Assert.IsTrue(HomePage.loggedInUserText.Contains("username"));
}
I'm using Firefox 43.0.2
Could someone help be to overcome this situation.
Thanks.
System.InvalidOperationException: No session ID specified occurs when you don't have valid driver instance in the method.
Please check Drivers._driverInstance is properly instantiated in your code. If possible post the Drivers class' relevant portions in the question.
Refer another SO question where the same problem is discussed: Disabling browser javascript with Selenium webdriver + specflow + c# + Pageobject + pagefactory
I am basically from Java, but observing the code and exception, i am excepting WebDriverWait is defined in SDDirectPage and calling here.right?
SDDirectPage._wait.Until(ExpectedConditions.ElementIsVisible(By.TagName("table")));
When you are calling defined wait method, you are not passing webdriver instance here. So i am expecting on switching to this method driver loosing the session. For sake of confirm, can you try executing the same by commenting this wait line (and my use something equivalent to Thread.sleep(5000) in Java for once to check this issue)
Thanks

Get Method, Class and LineNumber from StatckTrace in Application_UnhandledException event

I am developing Windows Phone 7 Silverlight Application. I want to do Application Level error handling instead of writing try...catch... in all methods. I need to extract Method Name, Class Name and Line Number where the actual error occurred. Below is the demo code. In Application_UnhandledException event, I am expecting Method = "GenerateError" and Class = "ExceptionTesting". Also, I want to get LineNumber where the actual error occurred (this is not shown in code).
Code to generate Error:
public partial class ExceptionTesting : PhoneApplicationPage
{
// Generate Error to Test Exception Handling
private void GenerateError()
{
Int16 i = Convert.ToInt16("test");
}
}
Code that Handles Application Level Exception:
// Code to execute on Unhandled Exceptions
private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
{
StackTrace st = new StackTrace();
var query = st.GetFrames() // get the frames
.Select(frame => new
{
Method = frame.GetMethod(),
Class = frame.GetMethod().DeclaringType
});
foreach (var q in query)
{
if (q.Method.Name.Contains("GenerateError"))
{
MessageBox.Show("Class: " + q.Class + ", Method: " + q.Method);
}
}
if (System.Diagnostics.Debugger.IsAttached)
{
// An unhandled exception has occurred; break into the debugger
System.Diagnostics.Debugger.Break();
}
}
The Application_UnhandledException method is not called from your method where the exception happens, so new StrackTrace() will not be meaningful, as you have discovered.
To get the stack trace for the place where the exception occurred, use e.Exception.StackTrace.
Note that the real exception may be wrapped inside another exception, possibly several layers deep (e.Exception.InnerException).
You could also use BugSense to get this information.
Disclaimer: I am one of the cofounders

Categories

Resources