asp.net Passing name of method as parameter to another method - c#

I tried to find answer how to use delegate for this example, but still I don't know how to use it for my code redundancy. I have this code which is repeated for each dbAction in my aplication:
public bool someDBMethod(params)
{
logDTO ldto = new logDTO("some text");
try
{
if (DALmethod(params)) //DB operation is successfull
{
Log.insertLog(ldto); //inserrt log to DB
return true;
}
catch (System.Data.SqlClient.SqlException ex)
{
Log.insertLog(changeLogStatus(ldto, errStatusEnum.ERR_SQL, ex.Message));
throw new Exception (ex.Message);
}
catch (Exception ex)
{
Log.insertLog(changeLogStatus(ldto, errStatusEnum.ERR, ex.Message));
throw new Exception (ex.Message);
}
}
This code is the same for different DB opperations except lines
logDTO ldto = new logDTO("some text");
if (DALmethod(params)) //DB operation is successfull
where I create DAL specific log and call the DAL method for insert/update/delete to database. Parameters for these DAL method aren't the same, but I could use some wrapper.
I would like to call for any DAL method
result = someDBMethod(DALmethod m, params p, logDTO l)
Thanks for your help

you could pass a Func<> as argument to your method.
public bool someDBMethod(Func<bool> callDalMethod, string message)
{
logDTO ldto = new logDTO(message);
try
{
if (callDallMethod()) //DB operation is successfull
{
Log.insertLog(ldto); //inserrt log to DB
return true;
}
catch (System.Data.SqlClient.SqlException ex)
{
Log.insertLog(changeLogStatus(ldto, errStatusEnum.ERR_SQL, ex.Message));
throw new Exception (ex.Message);
}
catch (Exception ex)
{
Log.insertLog(changeLogStatus(ldto, errStatusEnum.ERR, ex.Message));
throw new Exception (ex.Message);
}
Call this method:
someDBMethod(() => myDbMethod(param1, param 2), "message text");

Related

What value should I return in catch?

I just implemented a Try catch in my code, the error is because I have to return something in the catch,
I can't understand is "what should I return?"
'CompanyController.Create(DtoCompany)': not all code paths return a
value [API]
[HttpPost("create/")]
public async Task<ActionResult> Create([FromBody] DtoCompany dto_company)
{
try
{
var query = context.Companies.FirstOrDefault(x => x.rnc == dto_company.rnc);
if (query != null)
{
Company comp = mapper.Map<Company>(query);
context.Add(comp);
await context.SaveChangesAsync();
return Ok("Registro de compania exitoso");
}
else
{
return BadRequest($"Ya existe una compaƱia con este RNC: `{dto_company.rnc}`");
}
}
catch (Exception ex)
{
Console.WriteLine("Error From Company-Create:", ex.Message);
}
}
If I write the return this, I getting an other error:
catch (Exception ex)
{
return Console.WriteLine("Error From Company-Create:", ex.Message);
}
Cannot implicitly convert type 'void' to
'Microsoft.AspNetCore.Mvc.ActionResult' [API]
You should return an error telling your client what went wrong.
A good way to to this is to return Problem().
https://learn.microsoft.com/en-us/aspnet/core/web-api/handle-errors?view=aspnetcore-6.0
'CompanyController.Create(DtoCompany)': not all code paths return a
value [API]
I can't understand is "what should I return?"
If in the try block there's already a return statement, you could put the other return at the end of the function, and this in order to avoid multiple returns if multiple exceptions need to be handled:
try
{
//somecode
return Ok();
}
catch(Exception ex)
{
Console.WriteLine("Error From Company-Create:", ex.Message);
}
return BadRequest();// add this code
You shouldn't return anything from the catch part just a MessageBox or Console.WriteLine which you implemented on the first block...
Simply try catch statement is to ask compiler to do something and if any error occurred in the code simply catch it and show it me using a MessageBox or Console.WriteLine
Example:
try
{
sqlConnection conn = new sqlConnection(connection_string);
conn.Open();
}
catch (Exception ex)
{
if (ex.Message == "Certain specific error")
MessageBox.Show("Do not do it");
else
MessageBox.Show("Please do not do it");

Specific exception catch blocks does not work when throwing Exception inside Invoked method

In the code below, I have a catch block for System.UnauthorizedAccessException class exception.
try
{
var type = message.Form.GetObjTypeOf(typeof(BaseEntity));
MethodInfo updateFormStatusMethod = typeof(IFormService).GetMethod("UpdateFormStatus");
MethodInfo generic = updateFormStatusMethod.MakeGenericMethod(type);
var result = (bool)generic.Invoke(performanceformService, new object[] { message });
// I throw new System.UnauthorizedAccessException() inside 'UpdateFormStatus' method
}
catch (System.UnauthorizedAccessException)
{
// I'm waiting to get 'UnauthorizedAccessException' here
}
catch (System.Exception ex)
{
//But I get it here
}
I'm waiting to get 'UnauthorizedAccessException' in specific catch block but I get it in general catch block.

Inexplicable NullReferenceException that only occurs in production

We have an ASP.NET website running which throws a NullReference-exception along with a stacktrace and a line number that is simply impossible. And I can't make heads nor tails from it myself.
It says:
Exception at ReportService.GetReport(String reportType) in ReportService.cs:line 1458
which is funny, because that is this line:
var exports = new List<ReportExport>();
Thanks to the (very short) stacktrace, I can see that the error is triggered in the GetReport-function and not in the "GetAllUsers" or "GetAllUsersWithFilter" functions, because I would receive a different error message in my e-mailbox or I would see it pop up in the stacktrace.
So I suspect the line number is wrong, in which case there is only one other possibility and that is this line:
foreach (var userProfile in users) {
exports.Add(CreateUserProfile(userProfile));
}
But how could users ever be null?
Full (albeit simplified) code right here:
public function IList<ReportExport> GetReport(string reportType) {
try {
IQueryable<UserProfile> users = null;
switch (reportType) {
case "abc" :
users = GetAllUsersWithFilter();
break;
case default:
users = GetAllUsers();
break;
}
var exports = new List<ReportExport>();
foreach (var userProfile in users) {
exports.Add(CreateUserProfile(userProfile));
}
} catch (Exception ex) {
SendErrorMail("GetReport has failed", ex); /* I receive this error mail */
}
function IQueryable<UserProfile> GetAllUsers() {
try {
return dbContext.Users.Where(x => x.IsRegistered == true);
} catch (Exception ex) {
SendErrorMail("GetAllUsers", ex); /* I don't receive this e-mail */
return null;
}
}
function IQueryable<UserProfile> GetAllUsersWithFilter() {
try {
return GetAllUsers().Where(x => x.ExtraFilter == true);
} catch (Exception ex) {
SendErrorMail("GetAllUsersWithFilter", ex); /* I don't receive this e-mail */
}
}
function int GetNumberOfSessions(int userId) {
try {
return dbContext.Sessions.Count(x => x.UserId == userId);
} catch (Exception ex) {
SendErrorMail("GetNumberOfSessions", ex); /* I don't receive this e-mail */
}
}
function ReportExport CreateUserExport(UserProfile user) {
try {
var cnt = GetNumberOfSessions(user.Id);
return new ReportExport() {
UserId = user.Id,
NumberOfSessions = cnt
}
} catch (Exception ex) {
SendErrorMail(("CreateUserExport", ex);
}
}
If you are in production then you might be running with optimizations switched on - therefore the line number will be wrong.
But how could users ever be null?
But you are catching the Exception then returning null. You are relying on returning data - which may not be the case in GetAllUsers.
function IQueryable<UserProfile> GetAllUsers() {
try {
return dbContext.Users.Where(x => x.IsRegistered == true);
} catch (Exception ex) {
SendErrorMail("GetAllUsers", ex); /* I don't receive this e-mail */
return null;
}
}

Error Trapping Best Method

Hi I am trying to get a list of all trouble tickets but it says that not all codes paths return a value. Does Anybody no what I am doing wrong thanks
public List<TroubleTicket> GetAllTroubleTickets()
{
try
{
List<TroubleTicket> tickets = new List<TroubleTicket>();
var q = _supportDeskEntities.TroubleTickets.ToList();
return q;
}
catch (Exception ex)
{
}
}
If you catch an exception the function returns no value. So change this:
catch (Exception ex)
{
}
To this:
catch (Exception ex)
{
return null;
}
Or if you want it to return an empty list when an exception is catch then you can do this:
catch (Exception ex)
{
return new List<TroubleTicket>(0);
}
If we are taking about best practice then I would say that you should log the exception and then re-throw it. Like this:
catch (Exception ex)
{
//write to log
throw ex;
}
You need to return a value from the catch statement (or throw another exception within it). Otherwise, the function will return null
You can try this:
public List<TroubleTicket> GetAllTroubleTickets()
{
try
{
List<TroubleTicket> tickets = new List<TroubleTicket>();
var q = _supportDeskEntities.TroubleTickets.ToList();
return q;
}
catch (Exception ex)
{
return new List<TroubleTicket>(); // This is just in case you want to ignore any exceptions
}
}
or
catch (Exception ex)
{
throw new Exception("There was an error getting tickets"); // Probably not as good of a way as you lose the exception details
}
You only return a value if there is no exception thrown. You must either return from inside the catch block, or return outside the try/catch structure.
So you can either return in two separate places:
public List<TroubleTicket> GetAllTroubleTickets()
{
try
{
var q = _supportDeskEntities.TroubleTickets.ToList();
return q;
}
catch (Exception ex)
{
// You can also return "new List<TroubleTicket>()" if null is an unacceptable return value
return null;
}
}
or keep a return value variable, and set it in two different locations, and return it in one location:
public List<TroubleTicket> GetAllTroubleTickets()
{
List<TroubleTicket> tickets;
try
{
tickets = _supportDeskEntities.TroubleTickets.ToList();
}
catch (Exception ex)
{
// You can also use "new List<TroubleTicket>()" if null is an unacceptable return value
tickets = null;
}
return tickets;
}
You're not returning anything if an exception happens and you're not assigning the list to List<TroubleTicket> tickets but to a different variable. You could do:
public List<TroubleTicket> GetAllTroubleTickets()
{
List<TroubleTicket> tickets = null;
bool gotTickets = true;
try{
tickets = _supportDeskEntities.TroubleTickets.ToList();
}
catch (SpecificException ex){
gotTickets = false;
}
catch (Exception ex){ // catches all other "unexpected" exceptions
// log and/or...
throw;
}
return gotTickets ? tickets : null;
}
But you should not catch all kind of exceptions but only specific types that you expect. You also should log all other types of exceptions.
Your catch block is not returning anything.
public List<TroubleTicket> GetAllTroubleTickets()
{
List<TroubleTicket> tickets =null;
try
{
tickets = new List<TroubleTicket>();
var q = _supportDeskEntities.TroubleTickets.ToList();
return q;
}
catch (Exception ex)
{
//Log or handle your error
}
return tickets;
}

Returning result in nested try catch block

I am implementing some performance counters and I would like to know your opinion.
The question is should I declare response and return it outside try block or Is it OK to return it directly in the try block. Is there a difference and If so, what sample code is valid (if any).
With best regards, no9.
public string TestMethod(string document)
{
try
{
WebService ws = new WebService();
string response = null;
var startTime = PerformanceCounter.GetPerformanceCounterStartTimeHandle();
try
{
response = ws.InsertDocument(document);
}
catch (Exception ex)
{
PerformanceCounterHelper.Increment(PerformanceCounterEnum.NumberOfExternalWsCallsExceptionOnSec);
throw;
}
finally
{
PerformanceCounterHelper.IncrementPerformanceCounterByElapsedTime(PerformanceCounterEnum.DurationOfExternalCallsInSec, startTime);
PerformanceCounterHelper.Increment(PerformanceCounterEnum.NumberOfExternalCallsOnSec);
}
return response;
}
catch (Exception ex)
{
log.EventError(ex);
throw new DocumentGeneralException();
}
}
versus:
public string TestMethod(string document)
{
try
{
WebService ws = new WebService();
var startTime = PerformanceCounter.GetPerformanceCounterStartTimeHandle();
try
{
return ws.InsertDocument(document);
}
catch (Exception ex)
{
PerformanceCounterHelper.Increment(PerformanceCounterEnum.NumberOfExternalWsCallsExceptionOnSec);
throw;
}
finally
{
PerformanceCounterHelper.IncrementPerformanceCounterByElapsedTime(PerformanceCounterEnum.DurationOfExternalCallsInSec, startTime);
PerformanceCounterHelper.Increment(PerformanceCounterEnum.NumberOfExternalCallsOnSec);
}
}
catch (Exception ex)
{
log.EventError(ex);
throw new DocumentGeneralException();
}
}
As long as there isn't a difference because of not exiting (i.e. it runs additional/different code), then the code is identical. Actually, at the IL level it is illegal to ret from inside a try/catch, so one of the things the compiler does is to do exactly what you have done: introduce a local, assign the local inside the try/catch, then return that value when outside the try/catch.
Basically, go with whatever is simplest and most convenient to read. In your case, I would say "the first one".

Categories

Resources