Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JAVA api validation/Exception handling

How to handle error conditions when writing a Java API/Utility

This is my Implementation for my API interface

public void bin2zip(InputStream[] is,OuputStream os, String[] names)
{
   //if number of streams and number of names do not match do something 
}

What I am trying to do is handling a case when the length of the is != length of name.

How do i handle this. I dont want my API to do some work until ArrayOutOfBound exception to be thrown. I want to catch this early.

One solution is something like this:

if it does not match I throw

if(is.length==names.length)
            throws new Exception("ParemeterValidationException: The inputstream array and name array length should match");
if(containsInvalidFileName(names))
            throws new Exception("ParemeterValidationException: The names array length should contain valid filenames");

Also, can this be done compile time using DataDependency (I can make ValidationClass for the API and make sure the developer get hold of this object to pass on to this conversion API) or the runtime exception is the best way?

I believe doing a ValidationClass will make API use complicated

I did go through some materials (if anyone interested), but need some directions.

  1. http://lcsd05.cs.tamu.edu/slides/keynote.pdf
  2. Java: checked vs unchecked exception explanation
  3. http://docs.oracle.com/javase/tutorial/collections/interoperability/api-design.html
like image 934
Dexters Avatar asked May 23 '26 05:05

Dexters


1 Answers

Wherever possible, don't let end users screw it up.

public final class Bin2Zipper {
    private final List<InputStream> inputStreams = ...;
    private final List<String> names = ...;    

    public BinZipper() {
    }

    public void add(final InputStream is, final String name) {
        this.inputStreams.add(is);
        this.names.add(name);
    }

    public void bin2zip(final OutputStream os) {
        // ...
    }
}

A fluent interface might even be better. Then your code would look like:

Bin2Zipper.add(is1, name1).add(is2, name2).add(is3, name3).toZip(os);

public final class Bin2Zipper {

    private final List<InputStream> inputStreams = ...;
    private final List<String> names = ...;

    private Bin2Zipper(final InputStream is, final String name) {
         this.inputStreams.add(is);
         this.names.add(name);
    }

    public static Bin2Zipper add(final InputStream is, final String name) {
         return new Bin2Zipper(is, name);
    }

    public Bin2Zipper add(final InputStream is, final String name) {
         this.inputStreams.add(is);
         this.names.add(name);
         return this;
    }

    public void zip(final OutputStream os) {
        ...
    }
}

Where these fall down is when the client starts off with the two arrays. In that case, it can be annoying for them to have to loop over all the entries themselves. I think it's still worth it. If you don't, then you'll have to compare the sizes of the inputs right away. You almost certainly want to throw an unchecked exception, probably an IllegalArgumentException like Vince said.

like image 71
Eric Stein Avatar answered May 24 '26 17:05

Eric Stein



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!