I have the following code, but I am not sure what is the right pattern to exit the Execute() method.
The code is working, but the Execute() method is too large.
public void Execute()
{
// load datatable from excel
DataTable data = new();
try
{
data = ExcelReader.ToDataTable(_meta.FullPath, new() { SheetName = _sheetName });
}
// these errors are fine, but the dataset is not relevant and we want exit the execution
catch (ArgumentOutOfRangeException e)
{
if (e.Message.Contains("HeaderRowIndex")) return;
}
catch (ArgumentNullException e)
{
if (e.Message.Contains("Parameter 'sheet'")) return;
}
// execute logic on dataset
// ..
}
I would like to move the load data part of the code into separate method like this, but then I don't know how to end the execution.
public void Execute()
{
// load data
DataTable data = new();
LoadData();
// execute logic on dataset
// ...
}
private DataTable LoadData()
{
try
{
data = ExcelReader.ToDataTable(_meta.FullPath, new() { SheetName = _sheetName });
}
// these errors are fine, but the dataset is not relevant and we want exit the execution => but how?
catch (ArgumentOutOfRangeException e)
{
if (e.Message.Contains("HeaderRowIndex")) return; // will return to Execute() method, but not exit it.
}
catch (ArgumentNullException e)
{
if (e.Message.Contains("Parameter 'sheet'")) return; // will return to Execute() method, but not exit it.
}
}
I think this is very common issue, so what is the recommended way to handle this requirement? Should I create some returning object from the LoadData method, for example
class LoadDataResult
{
public DataTable data {get; set};
public bool IsRelevant {get; set};
}
dataResult = LoadData()
if (!dataResult.IsRelevant) return;
or it is an overkill and easier solution exist (to not populate program with these result objects)?
You can return data in the output parameter and return result of data loading as a primary method output (true for successful load, false for error that is fine):
private bool TryLoadData(out DataTable data)
{
data = null;
try
{
data = ExcelReader.ToDataTable(
_meta.FullPath, new() { SheetName = _sheetName });
return true; // loading succeeded
}
catch (ArgumentOutOfRangeException e)
when (e.Message.Contains("HeaderRowIndex"))
{
// loading failed, continue to Execute method
return false;
}
catch (ArgumentNullException e)
when (e.Message.Contains("Parameter 'sheet'"))
{
// loading failed, continue to Execute method
return false;
}
// otherwise exception propagates to Execute method
}
Usage:
public void Execute()
{
if (TryLoadData(out var data)
{
// execute logic on dataset
}
else
{
// error, but not exception
}
}
I would think about what you are trying to return. In your catch's you can log the error but you don't need to return. All code will flow back to the previous method that called it regardless if it returns or not. You only need to return if you need to pass a value back up to the previous calling method. Otherwise, you can just leave it be!
Related
I would like to update data using C# and Entity Framework Core.
But the result of Swagger is different from the result of executing the API in axios.
The variable "todoList" is stored with data in Swagger and returned null in axios.
Why a value of "todoList" is null?
Please tell me about it.
Thank you!
This is a Code.
public bool updateCompFlg(string operatorId, string id)
{
// Call Update!
// "_repository is an Interface."
if (_repository.Update(operatorId, id))
{
return true;
}
else
{
return false;
}
}
This is the code that actually updates the data.
public bool Update(string operatorId, string id)
{
// ★The results here are different.
var todoList = _context.TODOLIST.Where(u => u.seqNo.Equals(id)).FirstOfDefault();
todoList.operatorId = operatorId;
todoList.resultFlg = "1";
_context.Update(todoList);
try
{
_context.SaveChange();
return true;
}
catch (SystemException ex)
{
throw ex;
}
}
I have a very simple callback class that looks like this
class ActivityCallbacks
{
public class ActivityCallback : Java.Lang.Object, ICallbacks
{
Action<JSONObject> onSuccess;
Action<JSONObject> onFail;
public ActivityCallback(Action<JSONObject> success, Action<JSONObject> fail = null)
{
onFail = fail;
onSuccess = success;
}
public void FailCallback(JSONObject p0)
{
onFail?.Invoke(p0);
}
public void SuccessCallback(JSONObject p0)
{
onSuccess?.Invoke(p0);
}
}
}
The callback works fine if I use something like
someMethod(foo, new ActivityCallbacks.ActivityCallback(success=>...));#
This is fine, however there are occasions where I need to be able to use the value the callback is going to receive.
Currently I'm using this (which is incorrect)
someClass.SendFile(file, new ActivityCallbacks.ActivityCallback((r) =>
{
success =>
{
try
{
var newmessage = new ChatroomChatMessages(r.GetString("id"), r.GetString("original_file"), Utils.convertTimestampToDate(Java.Lang.JavaSystem.CurrentTimeMillis()), "Me :", true, "16", Constants.MyId, chatroomId);
addMessage(newmessage);
}
catch (Exception e)
{
//e.printStackTrace();
}
},fail => System.Console.WriteLine("failed to send")
}));
By the looks of the error generated, a semicolon is expected at the final success brace. However, this gives me an assignment error.
Am I approaching this the right way to obtain the value of the parameter the callback is expecting?
You need using success.GetString("id") in your try, because try is inner method of success action, r is be passed to success, you can only access sucess in try.
I'm currently loading images in different ways like this:
try {
// way 1
}
catch
{ // way 1 didn't work
try {
// way 2
}
catch
{
// etc.
}
}
I was wondering if there was a cleaner way to do this. Currently it's not a problem but if i add a few more ways it's going to get messy.
Note that the method loading the image is also in a try catch in the same way because it might not be an image.
It's basically trying a bunch of stuff to figure out what it is you dragged into the application.
You can write a method that accepts any number of delegates, attempting all of them and stopping after one of them runs successfully. This abstracts the exception handling into one place, and avoids all of the repetition:
public static void AttemptAll(params Action[] actions)
{
var exceptions = new List<Exception>();
foreach (var action in actions)
{
try
{
action();
return;
}
catch (Exception e)
{
exceptions.Add(e);
}
}
throw new AggregateException(exceptions);
}
This allows you to write:
AttemptAll(Attempt1, Attempt2, Attempt3);
If the methods compute a result you can create a second overload to handle that as well:
public static T AttemptAll<T>(params Func<T>[] actions)
{
var exceptions = new List<Exception>();
foreach (var action in actions)
{
try
{
return action();
}
catch (Exception e)
{
exceptions.Add(e);
}
}
throw new AggregateException(exceptions);
}
Assuming the "different ways" to load the image all throw an exception upon failure, you could iterate through the different ways, until one succeeds. The example below uses a Function<Image> to show a parameterless function that returns an image upon success. In your concrete example, you probably also have parameters into your function.
List<Function<Image>> imageLoaders = LoadTheListSomehow();
foreach (var loader in imageLoaders)
{
try
{
var image = loader();
break; // We successfully loaded the image
}
catch (Exception ex)
{
// Log the exception if desired
}
}
The nesting there does look unnecessary. I would isolate each way of loading an image into its own private method, and then called these methods as delegates in a loop, like this:
private static MyImage LoadFirstWay(string name) {
return ...
}
private static MyImage LoadSecondWay(string name) {
return ...
}
private static MyImage LoadThirdWay(string name) {
return ...
}
...
public MyImage LoadImage(string name) {
Func<string,MyImage>[] waysToLoad = new Func<string,MyImage>[] {
LoadFirstWay
, LoadSecondWay
, LoadThirdWay
};
foreach (var way in waysToLoad) {
try {
return way(name);
} catch (Exception e) {
Console.Error("Warning: loading of '{0}' failed, {1}", name, e.Message);
}
}
return null;
}
I'm maintaining a legacy WebForms application and one of the pages just serves GET requests and works with many query string parameters. This work is done in the code-behind and does a lot of this type of check and casting.
protected override void OnLoad(EventArgs e)
{
string error = string.Empty;
string stringParam = Request.Params["stringParam"];
if (!String.IsNullOrEmpty(stringParam))
{
error = "No parameter";
goto LoadError;
}
Guid? someId = null;
try
{
someId = new Guid(Request.Params["guidParam"]);
}
catch (Exception){}
if (!someId.HasValue)
{
error = "No valid id";
goto LoadError;
}
// parameter checks continue on
LoadError:
log.ErrorFormat("Error loading page: {0}", error);
// display error page
}
I'd like to create a testable class that encapsulates this parsing and validation and moves it out of the code-behind. Can anyone recommend some approaches to this and/or examples?
As a first big step, I'd probably create some form of mapper/translator object, like this:
class SpecificPageRequestMapper
{
public SpecificPageRequest Map(NameValueCollection parameters)
{
var request = new SpecificPageRequest();
string stringParam = parameters["stringParam"];
if (String.IsNullOrEmpty(stringParam))
{
throw new SpecificPageRequestMappingException("No parameter");
}
request.StringParam = stringParam;
// more parameters
...
return request;
}
}
class SpecificPageRequest
{
public string StringParam { get; set; }
// more parameters...
}
Then your OnLoad could look like this:
protected override void OnLoad(EventArgs e)
{
try
{
var requestObject = requestMapper.Map(Request.Params);
stringParam = requestObject.StringParam;
// so on, so forth. Unpack them to the class variables first.
// Eventually, just use the request object everywhere, maybe.
}
catch(SpecificPageRequestMappingException ex)
{
log.ErrorFormat("Error loading page: {0}", ex.Message);
// display error page
}
}
I've omitted the code for the specific exception I created, and assumed you instantiate a mapper somewhere in the page behind.
Testing this new object should be trivial; you set the parameter on the collection passed into Map, then assert that the correct parameter on the request object has the value you expect. You can even test the log messages by checking that it throws exceptions in the right cases.
Assuming that you may have many such pages using such parameter parsing, first create a simple static class having extension methods on NamedValueCollection. For example,
static class Parser
{
public static int? ParseInt(this NamedValueCollection params, string name)
{
var textVal = params[name];
int result = 0;
if (string.IsNullOrEmpty(textVal) || !int.TryParse(textVal, out result))
{
return null;
}
return result;
}
public static bool TryParseInt(this NamedValueCollection params, string name, out int result)
{
result = 0;
var textVal = params[name];
if (string.IsNullOrEmpty(textVal))
return false;
return int.TryParse(textVal, out result);
}
// ...
}
Use it as follows
int someId = -1;
if (!Request.Params.TryParseInt("SomeId", out someId))
{
// error
}
Next step would be writing page specific parser class. For example,
public class MyPageParser
{
public int? SomeId { get; private set; }
/// ...
public IEnumerable<string> Parse(NamedValueCollection params)
{
var errors = new List<string>();
int someId = -1;
if (!params.TryParseInt("SomeId", out someId))
{
errors.Add("Some id not present");
this.SomeId = null;
}
this.SomeId = someId;
// ...
}
}
I am writing a bunch of integration tests for a project. I want to call each individual integration point method wrapped in a try/catch block so that when it fails, I get some sort of feedback to display, rather than just crashing the app. I also want to be able to time how long the calls take, and check return values when needed. So, I have an IntegrationResult class with some basic description, result and time elapsed properties:
class IntegrationResult
{
private StopWatch _watch;
public string Description {get;set;}
public string ResultMessage {get;set;}
public bool TestPassed {get;set;}
public string TimeElapsed {get { return _watch == null ? "0" : _watch.Elapsed.TotalMilliseconds.ToString(); } }
public void Start()
{
_watch = StopWatch.StartNew();
}
public void Stop()
{
_watch.Stop();
}
}
The code I keep writing looks like this:
IntegrationResult result = new IntegrationResult();
result.Description = "T-SQL returns expected results";
try
{
result.Start();
SomeIntegrationPoint("potential arguments"); //This is the line being tested
result.Stop();
//do some check that correct data is present
result.TestPassed = true;
result.ResultMessage = "Pulled 10 correct rows";
}
catch(Exception e)
{
result.TestPassed = false;
result.ResultMessage = String.Format("Error: {0}", e.Message);
}
I would really like to be able to just pass the SomeIntegrationPoint method in as an argument and a delegate or something to check the results, but I can't figure out if that's even possible. Are there any frameworks to handle this type of testing, or do you have any suggestions on how I might simplify the code for better reuse? I'm tired of typing this block ;)
(I'm assuming this is C#, as tagged... though the syntax was not in the question.)
You can do this. Just change your result class to include:
class IntegrationResult
{
string Description { get; set; }
string SuccessResultMessage { get; set; }
string FailResultMessage { get; set; }
public IntegrationResult(string desc, string success, string fail)
{
this.Description = desc;
this.SuccessResultMessage = success;
this.FailResultMessage = fail;
}
public bool ExecuteTest(Func<IntegrationResult, bool> test)
{
bool success = true;
try
{
this.Start();
success = test(this);
this.Stop();
this.ResultMessage = success ?
this.SuccessResultMessage :
this.FailResultMessage;
this.TestPassed = true;
}
catch(Exception e)
{
this.TestPassed = false;
this.ResultMessage = String.Format("Error: {0}", e.Message);
success = false;
}
return success;
}
...
You could then change your code for your tests to:
private void myDoTestMethod(string argumentOne, string argumentTwo)
{
IntegrationResult result = new IntegrationResult(
"T-SQL returns expected results",
"Pulled 10 correct rows",
"Wrong number of rows received");
result.Execute( r=>
{
integrationPoint.call(argumentOne, argumentTwo);
//do some check that correct data is present (return false if not)
return true;
});
}
This can easily be extended to include your timings as well.
Have you looked into AOP? PostSharp looks like a nice place to start. There is also an example on exception handling aspects.