Proper Use of IllegalArgumentException

Original question here

I read in a UTF-8 file and parse the contents of this file. If there is an error in the file, there is no point in continuing, and execution should stop. I was asked to throw an IllegalArgumentException if there is a problem with the content, but the API document says:

Thrown to indicate that the method was passed an illegal or inappropriate argument.

In my code, the argument will be the file (or actually the path) that I pass, is it right to throw an IllegalArgumentException if something goes wrong during parsing? If not, what type of exception should I throw?

 private char[][] readMazeFromFile(Path mazeFile) throws IOException { if (!Files.isRegularFile(mazeFile) || !Files.isReadable(mazeFile)) { throw new IllegalArgumentException("Cannot locate readable file " + mazeFile); } List<String> stringList = Files.readAllLines(mazeFile, StandardCharsets.UTF_8); char[][] charMaze = new char[stringList.size()][]; for (int i = 0; i < stringList.size(); i++) { String line = stringList.get(i); if (line.length() != charMaze.length) throw new IllegalArgumentException(String.format("Expect the maze to be square, but line %d is not %d characters long", line.length(), charMaze.length)); if (line.contains("B")) { startX = i; startY = line.indexOf("B"); } if (line.contains("F")) { endX = i; endY = line.indexOf("F"); } charMaze[i] = line.toCharArray(); } if (startX == -1 || startY == -1) throw new IllegalArgumentException("Could not find starting point (B), aborting."); if (endX == -1 || endY == -1) throw new IllegalArgumentException("Could not find ending point (F), aborting."); return charMaze; } 
+6
source share
3 answers

I think the first use is correct:

 if (!Files.isRegularFile(mazeFile) || !Files.isReadable(mazeFile)) { throw new IllegalArgumentException("Cannot locate readable file "+mazeFile); } 

Since (as indicated in the documentation) an invalid file was specified as an argument, this should raise an IllegalArgumentException . Once you know that you have an actual file that meets these requirements, I personally do not think this is a good throw exception. This will force other developers to poll the type of argument that was specified, as opposed to the contents of the file. I think your options are:

  • Keep it as it is, just with very error messages explaining why this was an invalid argument.

  • Use another, potentially more applicable Java exception, such as java.text.ParseException , as this is parsing the file causing the error.

  • Create your own exception class that describes the problem with the file in more detail, for example. a MazeParseException (for comments) or FileFormatException .

I would expect the second or third option to become more useful if you expect several other developers to fulfill your function.

+5
source

Exceptions are basically nothing but names. My best advice here is to make your own. The main reason is that IllegalArgumentException are thrown exceptions because they extend java.lang.RuntimeException . They will simply cause problems if you have used them in this context. (A source)

Change the method signature to

 private char[][] readMazeFromFile(Path mazeFile) throws IOException, MazeParseException {...} 

And all throw new IllegalArgumentException with throw new MazeParseException (except for the first use as per @Joel's answer)

MazeParseException.java file:

 package yourPackage.here; import java.lang.Exception; public class MazeParseException { public MazeParseException() { super(); } public MazeParseException(String reason) { super(reason); } } 

The advantages of using your own exception are that you can mark additional data along with an exception related to your situation, for example, you can add:

 private int errorLineNum = null; public MazeParseException(String reason, int lineNum) { this(reason); this.errorLineNum = lineNum; } public int getMalformedLine() { return this.errorLineNum; } // And then update the toString() method to incorperate the errorLineNum @Override public String toString() { StringBuilder sb = new StringBuilder(super.toString()); if(errorLineNum != null) { sb.append("@ line #"); sb.append(this.errorLineNum); } return sb.toString(); } 
+1
source

Since the JSON or XML library sends its own execution if the file does not match what it is looking for (JSON file or XML file), I think you should do the same if it does not match what you are looking for (UTF file- eight).

IllegalArgumentException should be used for an internal problem in your code, and should not be thrown when your code is being debugged. Also, you should not catch IllegalArgumentException, and you probably want to catch it in your program.

0
source

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


All Articles