Reputation: 305
So I have a method that looks something like the following:
private static DataSet GetData()
{
DataSet returnValue = new DataSet();
try
{
//get all relevant tables here, add them to returnValue
}
catch (ArgumentException e)
{
//if a table isn't whitelisted, trying to grab it will throw an ArugmentException.
}
return returnValue;
}
Now, I want to pass along the caught exceptions. However, if for example 2 tables are whitelisted, but 1 isn't, I still want those two tables to be returned in the DataSet. I've been thinking I should do something like:
DataSet returnValue = new DataSet();
//TablesToFetch == string list or something containing tablenames you want to fetch
foreach (string tableName in tablesToFetch)
{
try
{
//get table tableName and add it to returnValue
}
catch (ArgumentException e)
{
//handle exception
}
}
return returnValue;
However, the problem here is that I can't just throw the exceptions I find, because then the DataSet won't be returned. The first solution I can think of is to "bundle" the exceptions and throw them one by one later, outside of the method*, but it kind of strikes me as a bit of a messy solution. Anyone have any tips on how to handle this, or should I just go ahead with the solution I just proposed?
*I could just wrap the method in another method, which calls a "handle all exceptions"-method after calling GetData()
Upvotes: 1
Views: 96
Reputation: 22038
If you can't solve 'the problem' within the method, you should throw an Exception. You shouldn't return a DataSet when an exception occurred (you didn't handled). So either you return an Exception or you return a DataSet and handle the exception within the method.
It is possible to Aggregate the exceptions like:
private DataSet GetData(IEnumerable<string> tablesToFetch)
{
var exceptions = new List<Exception>();
DataSet returnValue = new DataSet();
//TablesToFetch == string list or something containing tablenames you want to fetch
foreach (string tableName in tablesToFetch)
{
try
{
//get table tableName and add it to returnValue
}
catch (ArgumentException e)
{
//handle exception
exceptions.Add(e);
}
}
if (exceptions.Count > 0)
throw new AggregateException(exceptions);
return returnValue;
}
Another appoach is return a class with results:
public class GetDataResult
{
public GetDataResult(DataSet dataSet, string[] missingTables)
{
DataSet = dataSet;
MissingTables = missingTables;
}
public string[] MissingTables { get; private set; }
public DataSet DataSet { get; private set; }
}
private GetDataResult GetData(IEnumerable<string> tablesToFetch)
{
List<string> missingTables = new List<string>();
DataSet returnValue = new DataSet();
//TablesToFetch == string list or something containing tablenames you want to fetch
foreach (string tableName in tablesToFetch)
{
try
{
//get table tableName and add it to returnValue
}
catch (ArgumentException e)
{
//handle exception
missingTables.Add(tableName);
}
}
return new GetDataResult(returnValue, missingTables.ToArray());
}
usage:
var result = GetData(new[] { "MyTable1", "MyTable2" });
if(result.MissingTables.Count > 0)
{
Trace.WriteLine("Missing tables: " + string.Join(", ", result.MissingTables));
}
// do something with result.DataSet
update from comments
I don't know much about the structure you're using, so this is pseudo code
// PSEUDO!
private DataTable GetTable(string tableName)
{
// if table isn't found return null
if(<table is found>)
return table;
else
return null;
}
private GetDataResult GetData(IEnumerable<string> tablesToFetch)
{
List<string> missingTables = new List<string>();
DataSet returnValue = new DataSet();
//TablesToFetch == string list or something containing tablenames you want to fetch
foreach (string tableName in tablesToFetch)
{
var table = GetTable(tableName);
if(table == null)
{
missingTables.Add(tableName);
continue;
}
// do something with the table.
}
return new GetDataResult(returnValue, missingTables.ToArray());
}
Upvotes: 2
Reputation: 67291
This depends very much on the circumstances... I like an approach like this:
public returnType MyMethod([... parameters ...], out string ErrorMessage){
ErrorMessage=null;
try{
doSomething();
return something;
}
catch(Exception exp){
ErrorMessage=exp.Message;
return null; //
}
}
Instead of the out string you could create your own supi-dupi-ErrorInformation class. You just call your routine and check, wheter the ErrorMessage is null. If not, you can react on the out passed values. Maybe you want just to pass the exception out directly...
Upvotes: 2