I ´m doing a form where the user can Insert/Delete/Add entities. I´m using Winforms c# and entity framework 4.
Ok, the user can delete objects. Now, those objects can be referenced by other entities, so if the user wants to delete it, he will get an exception.
I catch that exception so as to show him a message that says that that object is begin used in other objects.
The exception I got is (UpdateException). But this exception can be raised if there is an update issue too. Is there any way to get the error code from Sql using this exception? Because I do have the error code that throws when this happens.
If I use SqlException I can check its number, but that's not the exception I´m receiving.
Do you mean you want to see the full exception or you want the user to the see the exception?
If you want to the see exception, you could write it to a text file:
try
{
// do something
}
catch(SQLException sqlex)
{
using (var file = new StreamWriter(#"C:\Users\Home\Desktop\sqlException.txt"))
{
file.WriteLine(sqlex.ToString());
}
}
catch(Exception e)
{
using (var file = new StreamWriter(#"C:\Users\Home\Desktop\generalException.txt"))
{
file.WriteLine(e.ToString());
}
}
This will write the exception to a text file on your desktop (change directories as appropriate).
Related
I am new to C# and Windows development in general. I need to use it to build an integration between our data in MySQL to Microsoft Dynamics GP (using eConnect). That part is not really relevant, but adds a little context to the examples below.
Ok, so when I connect to the service:
eConnectClient client = new eConnectClient();
string newCustomerDocument = "SOME_XML_HERE";
string connectionString = "Data Source=localhost;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=GPVPM;";
try
{
client.Open();
bool result = client.CreateEntity(connectionString, newCustomerDocument);
}
catch (FaultException<eConnectFault> e)
{
Console.Write("ECONNECT FAULT: " + e.ToString() + "\n");
}
Now, if I have an error in my XML, it will cause a FaultException to be thrown, but the resulting exception message is useless:
ECONNECT FAULT: System.ServiceModel.FaultException`1[GPConnect.eConnect.eConnectFault]: The creator of this fault did not specify a Reason. (Fault Detail is equal to GPConnect.eConnect.eConnectFault).
I found that if I look in the Event Viewer for Windows, it paints an entirely different picture of what happened:
Specifically:
Error Number = 250 Stored Procedure= taUpdateCreateCustomerRcd Error Description = The Tax Schedule does not exist in the Tax Schedule Master Table
So that is something actionable that can help me identify the problem and fix it.
The question:
With C#, how can I get the same level of details from an Exception as is recorded by the Event Manager?
The server may and may not return the detailed exception to the client. You may want to check
e.Detail /* of type GPConnect.eConnect.eConnectFault */
and
e.InnerException
inside the catch block for potential details.
I asked a question yesterday, and recieved great help (especially from #AviTurner).
I have further developed the program I was working on yesterday, and I have encountered a new problem.
The code of my program can be found here.
Basicly what it does, is:
The user can select a path of a directory, and the program scans all files for read-only attribute.
It sets the read-only attribute on those files that does not currently have it.
Now the problem occurs, when it encounters a file that is currently in use (such as system files).
I have been told there is no way around this, but I thought:
Is there a way to ignore the error (by this I mean continue the program, just skip this file); and add the name of the file to a list for later tracking purposes?
I hope I made my problem clear.
Thanks.
try surrounding your code in try/catch:
try
{
System.IO.FileAttributes attr = System.IO.File.GetAttributes(file);
}
catch(Exception ex)
{
files.add(file)
}
basically if you get an exception in the try block, the program executes the catch block
I suggest...
try
{
System.IO.File.SetAttributes(file, attr);
}
catch // You can specify a specific error with catch(UnauthorizedAccessException ex) for instance.
{
filesInError.Add(file); // A list<string>() to keep track of errors.
}
Here the details, and exceptions raised, by the SetAttributes().
SetAttributes on MSDN
And some explanations about try catch if you're not familiar with.
try ... catch on MSDN
I'm converting a product from System.Data.OracleClient to Oracle.DataAccess.Client, and came across a question Here's a snippet of some code:
try
{
//some db code
}
catch (System.Data.OracleClient.OracleException ex)
{
if (ex.Code == 00904)
{
// log specific error
}
}
The problem is, Oracle.DataAccess.Client.OracleException has no Code property. It has a Number property. Is this the same thing? The docs say this about the property -
This error number can be the topmost level of error generated by
Oracle and can be a provider-specific error number.
The Code property contained the ORA- error code.
Yes, they are the same thing. Oracle.DataAccess.Client.OracleException.Number is the same info as System.Data.OracleClient.OracleException.Code.
What will be proper way to catch exception which throw SQL server when I deleting data with Reference constraint from C# code.
I want to show my users message like:
"I can't delete the data because is used"
, rather than of showing message like this:
The DELETE statement conflicted with the REFERENCE constraint ... The conflict ccurred*in database "rampa", table "dbo.doc", column 'kartica_id'.
Use this:
try
{
//Execute delete statement
}
catch (SqlException sqlEx)
{
//Handle exception
}
finally
{
//Close connection
}
All sql errors are thrown as SqlException and there are no specific errors. To find out what was error exactly, there is property SqlException.Number which is the same as SQL Error Code. You can find the list of codes here.
You can access the ConstraintException and map its fields however you want to your own preferred error output.
using System.Data;
try
{
// code that violates constraint
}
catch (ConstraintException exc)
{
// build output message you wish using exc.Message and other fields,
// return cleanly or rethrow as your own exception
}
logging exception
the code below allows to save the content of an exception in a text file. Here I'm getting only the decription of the error.
but it is not telling me where the exception occured, at which line.
Can anyone tell me how can I achive that so I can get even the line number where the exception occured?
#region WriteLogError
/// <summary>
/// Write an error Log in File
/// </summary>
/// <param name="errorMessage"></param>
public void WriteLogError(string errorMessage)
{
try
{
string path = "~/Error/" + DateTime.Today.ToString("dd-mm-yy") + ".txt";
if (!File.Exists(System.Web.HttpContext.Current.Server.MapPath(path)))
{
File.Create(System.Web.HttpContext.Current.Server.MapPath(path))
.Close();
}
using (StreamWriter w = File.AppendText(System.Web.HttpContext.Current.Server.MapPath(path)))
{
w.WriteLine("\r\nLog Entry : ");
w.WriteLine("{0}", DateTime.Now.ToString(CultureInfo.InvariantCulture));
string err = "Error in: " + System.Web.HttpContext.Current.Request.Url.ToString()
+ ". Error Message:" + errorMessage;
w.WriteLine(err);
w.WriteLine("__________________________");
w.Flush();
w.Close();
}
}
catch (Exception ex)
{
WriteLogError(ex.Message);
}
}
#endregion
I find that the easiest way to log exceptions in C# is to call the ToString() method:
try
{
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
This usually gives you all the information you need such as the error message and the stack trace, plus any extra exception specific context information. (however note that the stack trace will only show you source files and line numbers if you have your application compiled with debug information)
It is worth noting however that seeing a full stack trace can be fairly offputting for the user and so wherever possible you should try to handle exceptions and print out a more friendly error message.
On another note - you should replace your method WriteLogError with a fully featured logging framework (like Serilog) instead of trying to write your own.
Your logging method is not thread safe (your log file will probably end up with log messages being intermingled with each other) and also should definitely not call itself if you catch an exception - this will mean that any exceptions that occur whilst logging errors will probably cause a difficult to diagnose StackOverflow exception.
I could suggest how to fix those things, however you would be much better served just using a proper logging framework.
Just log ToString(). Not only will it give you the stack trace, but it'll also include the inner exceptions.
Also, when you deploy a release build of your code to a production environment for instance, don't forget to include the .pdb files in the release package. You need that file to get the line number of the code that excepted (see How much information do pdb files contain? (C# / .NET))
Your solution is pretty good. I went through the same phase
and eventually needed to log more and more (it will come...):
logging source location
callstack before exception (could be in really different place)
all internal exceptions in the same way
process id / thread id
time (or request ticks)
for web - url, http headers, client ip, cookies, web session content
some other critical variable values
loaded assemblies in memory
...
Preferably in the way that I clicked on the file link where the error occurred,
or clicked on a link in the callstack, and Visual Studio opened up at the appropriate location.
(Of course, all you need to do is *.PDB files, where the paths from the IL code
to your released source in C # are stored.)
So I finally started using this solution:
It exists as a Nuget package - Desharp.
It's for both application types - web and desktop.
See it's Desharp Github documentation. It has many configuration options.
try {
var myStrangeObj = new { /*... something really mysterious ...*/ };
throw new Exception("Something really baaaaad with my strange object :-)");
} catch (Exception ex) {
// store any rendered object in debug.html or debug.log file
Desharp.Debug.Log(myStrangeObj, Desharp.Level.DEBUG);
// store exception with all inner exceptions and everything else
// you need to know later in exceptions.html or exceptions.log file
Desharp.Debug.Log(ex);
}
It has HTML log formats, every exception in one line,
and from html page you can open in browser, you can click
on file link and go to Visual Studio - it's really addictive!
It's only necessary to install this Desharp editor opener.
See some demos here:
Web Basic App
Web MVC App
Console App
Try to check out any of those repos and log something by the way above.
then you can see logged results into ~/Logs directory. Mostly anything is configurable.
I am only answering for the ask, other people have already mentioned about the code already. If you want the line number to be included in your log you need to include the generated debug files (pdb) in your deployment to the server. If its just your Dev/Test region that is fine but I don't recommend using in production.
Please note that the exception class is serializable. This means that you could easily write the exception class to disk using the builtin XmlSerializer - or use a custom serializer to write to a txt file for example.
Logging to output can ofcourse be done by using ToString() instead of only reading the error message as mentioned in other answers.
Exception class
https://learn.microsoft.com/en-us/dotnet/api/system.exception?redirectedfrom=MSDN&view=netframework-4.7.2
Info about serialization, the act of converting an object to a file on disk and vice versa.
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/serialization/