where the error coming from inside Try Catch - c#

I am doing 5 things inside a try/catch. If there is a error, how can i tell which function the error is coming from. so on line Console.WriteLine("Invalid operation"); I want it to display which function the error is so that its easy to debug.
I am trying to avoid using 5 different try/catch in Main OnGet() method. I was thinking to put try/catch inside each sub-method but I am return IQueryable so I wont be able to return error as type string. even so I will end up have 5 different if statement to check for error in OnGet()
How do you guys handle something like this?
public async Task<IActionResult> OnGetAsync(int p = 1, int s = 20)
{
try
{
// get all Data
IQueryable<MY_Model> Query = await _services.Get_All_CoursesTaken();
// Add Filters
Query = AddFilters(Query );
// Add Sorting
Query = AddSorting(Query );
// Add Paging
Query = AddPaging(p, s, Query );
//Display Data
My_List= await Query.AsNoTracking().ToListAsync();
}
catch (InvalidOperationException)
{
Console.WriteLine("Invalid operation");
}
return Page();
}
private IQueryable<MY_Model> AddFilters(IQueryable<MY_Model> Query)
{
//some code
}
private IQueryable<MY_Model> AddSorting(IQueryable<MY_Model> Query)
{
//some code
}
private IQueryable<MY_Model> AddPaging(int p, int s, IQueryable<MY_Model> Query)
{
//some code
}

Maybe your solution is:
Tuple
You can return IQueryable and String as return type in methods.
private Tuple<IQueryable<MY_Model>,string> AddFilters(IQueryable<MY_Model> Query)

Related

How to Call a method from a Class Library Variably

I am trying to find a solution that allows me to write one method in my forms project that can variably call multiple different methods from my class library project.
The reason for this being that I want to implement retry logic around these methods and prevent myself from repeating it for each different variety of method. The only consistent thing about the class library methods are that they all return Task<bool> so its easy to await on and perform logic with.
So far I have the following:
public async Task Runner(string methodName, params object[] parameters)
{
ThreadTimer.Start();
var tries = 0;
var ok = false;
while (tries <= 180)
{
try
{
var parameterTypes = (from p in parameters select p.GetType()).ToArray();
var mi = typeof(string).GetMethod(methodName, parameterTypes); //Currently returns null
var result = (Task<bool>)mi.Invoke(null, parameters);
ok = await result;
if (ok) break;
}
catch (Exception ex)
{
if (ex.InnerException == null)
{
ExceptionLabel2.Text = ex.Message;
}
else
{
ExceptionLabel1.Text = ex.Message;
ExceptionLabel2.Text = ex.InnerException.Message;
}
}
finally
{
tries++;
}
}
if (ok)
{
ThreadTimer.Dispose();
}
else
{
CShellControls.ExitWindowsEx(0, 0); //Logoff
}
}
The idea behind this is to declare a method name in a string and pass an array of parameters with it. I then used .GetMethod() to try and fetch the desired method info but unfortunately this returns null.
I have tried a few different methods but I'm open to suggestions and critique. As far as optimizing code goes I haven't really thought much into it, I just want to try and get this working first before approaching a more efficient method.
Thank you in advance!

Best way to make a return propagate

I couldn't find a answer to this, probably because I'm not asking this question in a proper way.
So, I'm writting a method that is inside a class, and at some point I want it to test for the formatting of a string. If it is not correct, I want it to show a message to the user, and to stop the execution, so that the user can fix that mistake. I have this:
if (Is not properly formated)
{
//get error information
//show error box with the formation error line
MessageBox.Show(String.Format(
"Error message{0}",
errorLine.ToString()), "Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
return;
}
Of course, this will stop the execution of this method, but I want to stop the execution of the main method (a button click method).
What is the best way to do this in C#?
You should really be using exceptions in C#, for example
private void Calculate(string[] lines)
{
try
{
lines.ForEach(Validate);
// process lines
}
catch(InvalidArgumentException ex)
{
MessageBox.Show(...);
}
}
private void Validate(string s)
{
if(s.IsNullOrEmpty)
throw new InvalidArgumentException(/* some details here*/);
}
You could write a validation method that returns true if the value is valid, and optionally return a string telling what is wrong:
private bool Validate(string s, out string error)
{
if (string.IsNullOrEmpty(s))
{
error = "s is null";
return false;
}
else
{
error = null;
return true;
}
}
Then call it:
string error;
if (!Validate(null, out error))
{
MessageBox.Show(error);
// Do something
}
Instead of the string you could use an enum if you want to structure the list of possible errors.

exception gets handled by the outermost try/catch. windows services

Function that throws the ThirdPartyException (I don't know how does their code work) exception:
private void RequestDocuments(/* arguments... */) {
while(true) {
var revision = lastRevision;
var fetchedDocuments = 0;
try {
foreach(var document in connection.QueryDocuments(revision)) {
if(fetchedDocuments > fetchQuota) return;
container.Add(document);
++fetchedDocuments;
Logger.Log.InfoFormat("added document (revision: {0}) into inner container", document.Revision);
}
Logger.Log.Info("Done importing documents into the inner container");
return;
}
catch(Exception ex) {
if(ex is ThirdPartyException) {
// handle this in a certain way!
continue;
}
}
}
}
this function is called inside a worker thread like this:
private void ImportDocuments() {
while(!this.finishedEvent.WaitOne(0, false)) {
try {
var documents = new List<GohubDocument>();
RequestDocuments(remoteServerConnection, documents, lastRevision, 100);
}
catch(Exception ex) {
// here is where it really gets handled!!!?
}
}
}
the exception is handled only in the outermost (which is inside the ImportDocuments method) try/catch.
Why is that?
If that's a LINQ API which exposes IQueryable you don't get an error due to the deferred execution that LINQ to SQL implementations typically uses.
To prevent it you have to invoke .ToList(), FirstOrDefault() etc within your first method. That makes sure that the query really have been executed against your data source.
Solution:
var documents = connection.QueryDocuments(revision).ToList();
foreach(var document in documents) {
if(fetchedDocuments > fetchQuota) return;
// [...]
}

How to check if ObjectResult<> contains a value

How do I check to see if the ObjectResult<> has a value or not? Right now it's returning values but will it throw an exception is there is nothing to return?
This is the section of code that I need to check so I do not have to depend on a try catch block
iProjInfo.ProjectLeafs = db.proc_GetProjectLeafs(projectID).ToList<IProjectLeafs>();
public static Task<IProjectInfo> GetProjectInfo(int projectID)
{
return Task.Run(() =>
{
using (var db = new StorefrontSystemEntities())
{
IProjectInfo iProjInfo = db.proc_GetProject_ForDrawings(projectID).Single<IProjectInfo>();
try
{
iProjInfo.ProjectLeafs = db.proc_GetProjectLeafs(projectID).ToList<IProjectLeafs>();
}
catch (Exception ex)
{
}
return iProjInfo;
};
});
}
As long as the stored procedure is getting executed and returning a result set; even if it is empty (no records returned by the stored procedure), you can be sure of an empty list being returned.

Catch and Continue

I want an extension method or generic method where I want code execution to continue even there is some exception and keep recording the exceptions in a list. This is an example what I tried
public void ValidateName()
{
if (_customer.Name.Length < 5)
throw new Exception("shortname");
}
public void ValidateAge()
{
if (_customer.Age < 5)
throw new Exception("short age");
}
internal void Validate()
{
this.CatchAndContinue(delegate()
{
this.ValidateName(); // throws exception and add to list
this.ValidateAge(); // but this should also execute
});
}
public void CatchAndContinue(Action action)
{
try
{
action();
}
catch (Exception ex)
{
exceptions.Add(ex);
}
}
For current class I can pass exceptions to ValidateName and ValidateAge method, but I want if we can do the way I want, with little change in validate() method body. I know semantically it sounds weired but I need lot of places to do this. Or if there is something better to achieve it
EDIT
This validation is simple example, not in all scenerio it will be validator only. By the way in this case I want to provide UI the list of errors and why throw, because when model constructed from DB (due to wrong data in DB) such objects should not be created. These are just examples of concern
Don't use exceptions for control flow.
Instead, your validate method should return a bool, and let the client of the validate method decide what to do. One step beyond that is return a ValidationResult with a ValidationStatus property that indicates success or failure and a Message property that records the reason that validation failed.
Yield / return may be useful to you.
http://msdn.microsoft.com/en-us/library/9k7k7cf0%28v=vs.80%29.aspx
Does it have to be exceptions?
To clarify:
internal IEnumerable<string> Validate()
{
if( _customer.Age > 5 ) { yield return "Too Old"; }
if( _customer.Name.Length < 3 ) { yield return "Not enough name characters"; }
}
// using it
IEnumerable<string> errors = myCustomer.Validate();
if( errors.Length > 0 ) {
// uh oh, print out the errors!
foreach( string error in errors ) {
MsgBox(error);
}
}
Instead of throwing exceptions in the Validate methods, I would add to the exceptions list and return a bool value indicating success/failure (return part is optional, add it only if you care about the status of validation).
Something like:
public void ValidateName()
{
if (_customer.Name.Length < 5) {
LogValidationFailure("shortName"); // you can add more params if needed
return; // or return false if you need it
}
// do normal business here
}
Not only is this cleaner, it is better performing since try/catch and exception throwing are expensive.

Categories