C # is good practice to simplify exceptions thrown by System.IO.File.ReadAllText

Obviously, many applications will need to work with files and display errors for users. However, members of the System.IO.File class throw many exceptions. This is for ReadAllText only:

  • ArgumentException
  • ArgumentNullException
  • PathTooLongException
  • DirectoryNotFoundException
  • IOException
  • UnauthorizedAccessException
  • FileNotFoundException
  • NotSupportedException
  • SecurityException

So, how to catch them all and display them to the user without swallowing other exceptions?

Obviously, with perfect coding, you can eliminate these 2:

  • ArgumentException
  • ArgumentNullException

If you write a (possibly sick) check, you can throw a PathTooLongException. But why are you duplicating code to verify what Microsoft has written?

But other exceptions are possible, even if you have completed all the checks:

  • DirectoryNotFoundException
  • IOException
  • UnauthorizedAccessException
  • FileNotFoundException
  • NotSupportedException
  • SecurityException

Files and folders may be deleted by the time the file is opened, security permissions may change, etc.

I do not see what you can do in these scenarios other than displaying a message to the user. Are you going to find a directory that the OS cannot find? Fix permissions? Enter code in OS to support unsupported operation? lol All I see is showing an error message.

So, if I need to catch all of these exceptions every time I open the file to read the text, my code should be long and iterative, unless I swallow the exceptions by catching the Exception.

Would it be good practice to throw a FileException and just catch all the exceptions that might occur when working with files? I had in mind the following:

public class FileException : Exception { public FileException( Exception e ) : base( e.Message, e.InnerException ) { } } public static class FileNoBS { public static string ReadAllText2( string path ) { try { return File.ReadAllText( path ); } catch ( ArgumentNullException e ) { throw new FileException( e ); } catch ( ArgumentException e ) { throw new FileException( e ); } catch ( PathTooLongException e ) { throw new FileException( e ); } catch ( DirectoryNotFoundException e ) { throw new FileException( e ); } catch ( FileNotFoundException e ) { throw new FileException( e ); } catch ( IOException e ) { throw new FileException( e ); } catch ( UnauthorizedAccessException e ) { throw new FileException( e ); } catch ( NotSupportedException e ) { throw new FileException( e ); } catch ( SecurityException e ) { throw new FileException( e ); } } } 

Then when you catch exceptions, I just would have to write this:

  try { string text = FileNoBS.ReadAllText2( path ); } catch ( FileException e ) { // display error to user } 

I really don't understand why Microsoft did not group all these togather exceptions in some way. Am I missing something or is this a good practice?

+6
source share
2 answers

The exceptions you pointed out are in two different categories - this indicates a coding error, and this indicates a problem at runtime. You are absolutely right that exceptions in the first category can be prevented: you can write code in such a way that they never happen. For example, if your code is a null -check path, you do not run the risk of ever getting an ArgumentNullException in a ReadAllText call. Analyze the remaining exceptions one by one:

  • IOException , DirectoryNotFoundException , FileNotFoundException - all three will be caught if you catch an IOException
  • UnauthorizedAccessException - need to be caught separately
  • NotSupportedException - can be prevented by checking the path before making a call.
  • SecurityException - you can prevent permission checking before making a call.

In the end, you can cover all exceptions that indicate problems at runtime by catching an IOException and UnauthorizedAccessException and preventing the rest of the exceptions by first checking the parameters you plan to pass and examining the runtime of your code.

+4
source

What are you looking for, System.IO.IOException .

System.IO.IOException's inheritance hierarchy:

 System.Object System.Exception System.SystemException System.IO.IOException System.IO.DirectoryNotFoundException System.IO.DriveNotFoundException System.IO.EndOfStreamException System.IO.FileLoadException System.IO.FileNotFoundException System.IO.PathTooLongException System.IO.PipeException 

ArgumentException, in particular, is inherited by two well-known exceptions:

 System.Object System.Exception System.SystemException System.ArgumentException System.ArgumentNullException System.ArgumentOutOfRangeException //... 

Some typical ArithmeticException exceptions:

 System.Object System.Exception System.SystemException System.ArithmeticException System.DivideByZeroException System.NotFiniteNumberException System.OverflowException 

Also noteworthy is the ThreadAbortException , which should be caught in the asynchronous event delegates used in desktop applications, or also in ASP.NET when redirecting / terminating the HttpResponse.

Other exceptions are too simple to have more "specialized base exceptions." Look for them in the link System.Exception inheritance hierarchy and in the System.SystemException inheritance hierarchy or by reflection.

+3
source

Source: https://habr.com/ru/post/945926/


All Articles