0

I am a green C# programmer and I'm trying to add exception handling to an application but unsure of the correct way to achieve the result I'm looking for. I'm parsing a CSV and grabbing values that are always in the same place. If a blank or incorrectly formatted file comes through it will cause the application to crash and I want to prevent this. Instead of storing the value from the file, if an exception occurs I want to store a single whitespace character in the string variable. Here is my code:

using (StreamReader inputGetData = new StreamReader(filename.FullName))
            {
                //STORE DATA STRIPPED FROM MDT FILE
                lotID = inputGetData.ReadLine().Split(',')[2];
                exatronFile = inputGetData.ReadLine().Split(',')[2];
                rofinFile = inputGetData.ReadLine().Split(',')[2];
                lotQty = inputGetData.ReadLine().Split(',')[2];
                serialize = inputGetData.ReadLine().Split(',')[2];
                serialStart = inputGetData.ReadLine().Split(',')[2];
                serialInc = inputGetData.ReadLine().Split(',')[2];
                partNum = inputGetData.ReadLine().Split(',')[3];
                inputGetData.ReadLine();
                dieMNF = inputGetData.ReadLine().Split(',')[3];
                assemblySub = inputGetData.ReadLine().Split(',')[3];
                countryOrigin = inputGetData.ReadLine().Split(',')[3];
                dateCode = inputGetData.ReadLine().Split(',')[3];
                QMLcomp = inputGetData.ReadLine().Split(',')[3];
                prefix = inputGetData.ReadLine().Split(',')[3];
                serialNum = inputGetData.ReadLine().Split(',')[3];
                suffix = inputGetData.ReadLine().Split(',')[3];
                inputGetData.ReadLine();
                packageCode = inputGetData.ReadLine().Split(',')[1];

So ideally I want to try each line, catch an exception if it occurs, throw it to the higher method for logging and then store ' ' into the variable. If I put that last part into the finally block it will always run even if an exception doesn't occur correct? How can I achieve this?

  • 2
    You can avoid the exceptions entirely if you do null and length checks instead of chaining the expressions. If you know how to avoid an exception by testing the condition beforehand, you should do that. – madreflection Dec 19 '19 at 19:06
  • 2
    Why not rather make a method that reads a line, splits it, checks if there are enough items or not and then returns accordingly? Exceptions are for exceptional situations and there’s no reason to repeat the same piece of code here all the time – Sami Kuhmonen Dec 19 '19 at 19:07
  • Here's a random tip for parsing CSV files: look into the CsvHelper package. It's not necessary but it can make things a little easier. – Slothario Dec 19 '19 at 19:08
  • Thank you all for your timely responses! @SamiKuhmonen This looks like a perfect idea, I appreciate it! – Mitchel Belmer Dec 19 '19 at 19:11
  • look into the safe navigation operator `?.` as well –  Dec 19 '19 at 19:15
  • One way to do this is to write a function (that returns `IEnumerable`) that contains a `yield return` iterator block. Its role is to read the stream a line at a time, do the split and then `yield return` the result. Then wrap that in another function that returns an IEnumerable and that takes an index into the string, `yield return`ing the appropriate field. If you provided the contents of your file (so I didn't have to mock one up) and the declarations of all your variables (again, I really don't feel like typing them all up), I could throw something together – Flydog57 Dec 19 '19 at 19:17
  • So this application handles multiple files at once or just one depending on how many files enter the watched folder. Say instead of putting in a blank value I wanted to break away from the process, add to my log file that the format isn't correct and move onto the next file, what would be a good way to tackle that? I don't really want to post the entire app unless necessary but most everything takes places in a foreach file in files that is triggered by a FileSystemWatcher. – Mitchel Belmer Dec 19 '19 at 19:26
  • 2
    The CSV format is more complicated than you realize and `Split` [does not parse CSV](http://www.secretgeek.net/csv_trouble). There are many [CSV parsers](https://stackoverflow.com/questions/2081418/) available that will handle them correctly. – Dour High Arch Dec 19 '19 at 19:29

2 Answers2

0

As suggested in the comments, there are some packages that can simplify your life.

If you want to do things in the hard way (nothing against that :p) you can always add a middle step by using a (even local) function:

    string Extract(string s, int position)
    {
        var split = s.Split(',');
        return split.Length > position ? split[position] : " ";
    }

    lotID = Extract(inputGetData.ReadLine(), 2);
Alvin Sartor
  • 2,249
  • 4
  • 20
  • 36
0

You could use the following function call for every assignement :

public T TryCatch<T>(Func<T> tryCatched, T returnedOnFailure)
{
    try
    {
        return tryCatched();
    }
    catch
    {
        return returnedOnFailure;
    }
}

If you want to gather information about the exception that happened you could have an out Exception exception as last parameter.

To call it just do lotID = TryCatch(() => inputGetData.ReadLine().Split(',')[2], " "); for your case

nalka
  • 1,894
  • 11
  • 26