You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 19 Next »

An in-band error indicator is a type returned by a function that can either indicate a legitimate return value, or an illegitimate value that indicates an error of some sort. Some common examples of in-band error indicators include:

  • A valid object or null
  • An integer indicating a positive value, or -1 to indicate that an error occurred
  • An array of valid objects or null indicating no valid objects

In-band-error indicators require checking for the error; however this checking is often overlooked. In addition to violating EXP00-J. Do not ignore values returned by methods, this has the unfortunate effect of invalid values being treated as valid in future computations.

Avoid the use of in-band error indicators. They are much less common in Java than in some other programming languages, but they are used in the read(byte[] b, int off, int len) and read(char[] cbuf, int off, int len) families of methods in java.io.

In Java, the best way to indicate an exceptional situation is by throwing an exception rather than by returning an error code. Exceptions are propagated across scopes and cannot be ignored in the same way that error codes can. When using exceptions, the error-detection and error-handling code is kept separate from the main flow of control. Also, exceptions can be used in situations where error codes cannot be returned (in constructors, for example).

Noncompliant Code Example

This noncompliant code example attempts to read into an array of characters and add an extra character into the buffer immediately after the characters read:

static final int MAX = 21;
static final int MAX_READ = MAX - 1;
static final char TERMINATOR = '\\';
int read;
char [] chBuff = new char [MAX];
BufferedReader buffRdr;

// Set up buffRdr

read = buffRdr.read(chBuff, 0, MAX_READ);
chBuff[read] = TERMINATOR;

However, if the input buffer is initially at end-of-file, then the read method will return −1, and the attempt to place the terminator character will throw an ArrayIndexOutOfBoundsException.

Compliant Solution (Wrapping)

This compliant solution defines a readSafe method that wraps the original read method and throws an exception if end-of-file is detected:

public static int readSafe(BufferedReader buffer, char[] cbuf, int off, int len) throws IOException {
  int read = buffer.read(cbuf, off, len);
  if (read == -1) {
     throw new EOFException();
  } else {
     return read;
  }
}

// ...

BufferedReader buffRdr;

// Set up buffRdr

try {
   read = readSafe(buffRdr, chBuff, 0, MAX_READ);
   chBuff[read] = TERMINATOR;
} catch (EOFException eof) {
   chBuff[0] = TERMINATOR;
}

Applicability

Using in-band error indicators may result in programmers failing to check status codes or using incorrect return values, leading to undefined behavior.

Given the comparatively rare occurrence of in-band error indicators in Java, it may be possible to compile a list of all methods that use them and automatically detect their use. However, detecting the safe use of in-band error indicators is not feasible in full generality.

Bibliography

 


  • No labels