What class throws the exception in the end? - c#

I have two methods:
public void MethodOne()
{
try {
MethodTwo();
}
catch (Exception ex) {
Log.Message("Something went wrong);
throw;
}
}
public void MethodTwo()
{
try {
// Some logic that fails
}
catch (Exception ex) {
throw ex;
}
}
I'm calling MethodTwo from MethodOne. If a exception is thrown in MethodTwo. Will the program terminate after the exception has been handled there or will it bubble up to MethodOne and be catched there aswell?

The exception will be catched and rethrown in MethodTwo and then catched and rethrown again in MethodOne.
Whether the application will terminate depends on how and where you call MethodOne and whether you catch the exception when calling MethodOne or further up the call chain.
Note that throw ex resets the stack trace and should be avoided.

The program will be terminated in MethodOne.
You can understand more from this article. Throw and Re-throw Exceptions in C#
Be aware, by throwing the exception will destroy the stack trace information!

Related

How to get rid of class name prefix in custom exception message?

Is there a way to get rid of the class name prefix which is added to message while throwing exception?
public class MyException: Exception
{
public MyException(string message) : base(message){}
}
and then
throw new MyException("error");
will by displayed in console as "MyException: error", but I want it to be just "error".
I'm guessing you're writing it as the following, which prints the string representation of the exception:
try
{
// Exception is thrown
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
You can instead use, which will only write the exception message:
Console.WriteLine(ex.Message);

Where to use exception handling

I have an MVC controller that uses a payment service class. Where should I do the exception handling? What is best practice?
Do I use try/catch blocks in both my controller and service class?
Is the exception just thrown again in the service class so it can be handled in the controller? Or should all the exception handling be done in the controller?
I can catch Stripe specific exceptions, should that be done in the service class or controller? Confused...
public async Task<IActionResult> DoSomething(MyViewModel model)
{
try
{
await _paymentService.UpdateSomethingAsync(id, token);
}
catch (Exception ex)
{
//handle
}
enter code here
}
public class PaymentService : IPaymentService
{
public async Task UpdateSomethingAsync(string id, string token)
{
try
{
//update using Stripe...
}
catch (Exception ex)
{
//TODO: Implement error handling
throw;
}
}
}
I guess exception handling must be at service level as it should be self capable of catching and handling all the exceptions(also, to log it at service level for later analysis) occurred at service level and throwing it in its original form (or as per the need it can be customized at service level) to the receiver.
Receiver (controller in this case) should have it's own error handling mechanism as it is a different layer of application and may require some manipulation over exceptions or it's logging at UI level. Here, note that if there is no manipulation or logging of exception or error is required you can directly show service level exception and remove catch from controller.
Hope it make sense.
just write the same code in catch which is in try{ } because catch never pass back or return the value .
try
{
cust_id = txtID.Text;
submit changes();
lblmessage.Text = "Data Save";
}
catch (Exception ex)
{
lblmessage.Text = "Saving error";
cust_id = txtID.Text;
submit changes();
}

C# Exception: Does it have an unique value/identifier

Does the class Exception have an unique Id or any other unique modifier (GUID,... )?
I'm logging the generated exceptions inside a backend-service. But my goal is to only log each exception once.
Perhaps an example might of some use here:
The Service has 3 layers:
DAL (SQL-Interaction)
=> Exception A occurs here and is being logged into the database
BL (BusinessLayer)
=> Exception A is passed to here but isn't being logged
=> Exception B is thrown here and is being logged into the table
Services (Service Interface)
=> Exception A is passed to here but isn't being logged
=> Exception B is passed to here but isn't being logged
...
Client-solutions
My current solution (which i personnally really don't like):
I've written a own exception (inherits from the base class exception). when any exception is thrown for the first time then its being logged. Then its being cast to my own exception and rethrown. Exceptions of type of my own exceptions are nog logged in the database
example (This is pseudo code)
DAL - Layer
try{}
catch (Exception e)
{
// log in database
// log in logfile
// Cast to OwnException
// rethrown as OwnException
}
BL - Layer
try{}
catch (OwnException e)
{
// log in logfile
// rethrow e
}
catch (Exception e)
{
// log in database
// log in logfile
// Cast to OwnException
// rethrow as OwnException
}
Update: What i'm actually looking for is an Id/unique modifier. I would scan the database for the presence of this id. And if this id isn't present then i would write a record. If its present then it would just be rethrown.
You can create your Exception and create a new propertie boolean as "Logged" , when you log the exception you set true to "Logged" and in your anothers layers before log you need to verify if is not logged.
public class YourException : ApplicationException
{
public YourException () { }
public YourException (string message) : base(message) { }
public YourException (string message, Exception innerException) : base(message, innerException) { }
public bool LoggedInLogFile { get; set; }
public bool LoggedInDataBase { get; set; }
}
In your DAL:
try{}
catch (Exception e)
{
// log in database
// log in logfile
var ex = new YourException (e.Message);
ex.LoggedInLogFile = true;
ex.LoggedInDataBase = true;
throw ex;
}
In your Service Layer:
try{}
catch (YourException e)
{
if(!e.LoggedInLogFile)
//Log in file
if(!e.LoggedInDataBase)
//Log in Database
}
I wouldnt create my own custom exception. What I would do is explicitly catch the exceptions I know can occur in the DAL, For example an SQLException. In the BL catch specific exceptions that can occur there, and let the rest propogate upwards.
It is unlikely that your BL and DAL would need to log the same exceptions, seperate them so each of them catches the set they are responsible for, and then rethrow them so the client UI can catch them.
Edit
Forgot to mention, make sure when you rethrow to use:
throw,
And not:
throw ex;
So you wont lose your stacktrace

Wcf service exception good practices

I am developing a distributed application. In it, there are roles and sets of permissions that I must validate.
Is a good pratice to throw an exception, in per example, unauthorized access?
Or should I send some message back to the client?
On your service operation, you can specify a FaultContract that will serve both purposes like so:
[OperationContract]
[FaultContract(typeof(MyServiceFault))]
void MyServiceOperation();
Note that MyServiceFault must be marked with DataContract and DataMember attributes, in the same way you would a complex type:
[DataContract]
public class MyServiceFault
{
private string _message;
public MyServiceFault(string message)
{
_message = message;
}
[DataMember]
public string Message { get { return _message; } set { _message = value; } }
}
On the service-side, you are then able to:
throw new FaultException<MyServiceFault>(new MyServiceFault("Unauthorized Access"));
And on the client-side:
try
{
...
}
catch (FaultException<MyServiceFault> fault)
{
// fault.Detail.Message contains "Unauthorized Access"
}
Well, you can catch all exceptions in the WCF service implementations methods and rethrow them as FaultExceptions. By doing it this way, the exception will be rethrown on the client with a message of your choosing:
[OperationContract]
public List<Customer> GetAllCustomers()
{
try
{
... code to retrieve customers from datastore
}
catch (Exception ex)
{
// Log the exception including stacktrace
_log.Error(ex.ToString());
// No stacktrace to client, just message...
throw new FaultException(ex.Message);
}
}
To avoid having unexpected errors relayed back to the client, it's also a good practice to never throw Exception instances in code on the server-side. Instead create one or more of your own exception types and throw them. By doing so, you can distinguish between unexpected server processing errors and errors that are thrown due to invalid requests etc:
public List<Customer> GetAllCustomers()
{
try
{
... code to retrieve customers from datastore
}
catch (MyBaseException ex)
{
// This is an error thrown in code, don't bother logging it but relay
// the message to the client.
throw new FaultException(ex.Message);
}
catch (Exception ex)
{
// This is an unexpected error, we need log details for debugging
_log.Error(ex.ToString());
// and we don't want to reveal any details to the client
throw new FaultException("Server processing error!");
}
}
Throwing general Dot Net Exceptions would make the service client proxies and the server channel to go in faulted state if you are not using basicHTTPBinding ...To avoid that you should always throw FaultException from the service...
from you catch block just use:
throw new FaultException("Your message to the clients");

Custom exception class to alert errors and log

I am writting an API for some data manipulation these days and I have faced a question that I cannot answer myself :D
I have made an exception class that extends the .net Application Exception class because I want to add some functionality there to be executed everytime the API throws an exception.
For example I want to alert the error message and stacktrace via sms and email and I want to log the inner exception via Log4net. I don't know if this is a good aproach to use with the custom exception class or if I overused the meaning of the custom exceptions.
I have read this article about how to extend the Exception in c#
so here we go with my example of code :
public class CustomExceptionClass : Exception
{
/// <summary>
/// I use custom functionality here everytime this exception occures
/// </summary>
/// <param name="errorMessage">error message</param>
/// <param name="innerEx">Inner exception that cause this exception</param>
public MyCustomException(string errorMessage, Exception innerEx) : base(errorMessage, innerEx)
{
//log exception
_log.ErrorFormat(errorMessage, innerEx);
//alert via sms and email
AlertMailer.SendAlertMessage(errorMessage, innerEx, innerEx.Message);
}
}
I think that doing logging and alerting by throwing a custom exception is a valid technique.
However, you shouldn't do the logging and alerting in the exception constructor. Instead you should catch the custom exception in all entry-points to your API and do the logging and alerting in the catch block. For example:
void MyApiFunction()
{
try
{
// do data manipulation
}
catch(MyCustomException ex)
{
_log.ErrorFormat(ex.ErrorMessage, ex.InnerEx);
AlertMailer.SendAlertMessage(ex.ErrorMessage, ex.InnerEx);
}
}
I would recomend you to use AOP instead.
PostSharp exception handling
Custom exceptions should be used to define different types of exception.
Exceptions from the database
Exceptions from file io
Exceptions from web services
They should be very simple, and contain no other logic than assigning variables. Why? Because if the exception constructor throws another exception you are going to have a hard time tracing it.
The ways i handle those exceptions are:
AOP (Spring.NET)
Specific try/catches
The global exception handler
In a program
namespace ConsoleApplication1 {
class Program {
static void Main(string[] args) {
try {
//do something
} catch(Exception e) {
//log error
}
}
}
}
Or in a web site
public class ApplicationErrorModule : IHttpModule {
public void Init(HttpApplication context) {
context.Error += new EventHandler(context_Error);
}
private void context_Error(object sender, EventArgs e) {
//log error
}
}
Heavy treatments like logging and sending an email don't belong in the constructor of the exception. You should instead handle the exception using AOP as #petro suggested, or in a catch statement.

Categories