Error Handling
Most HEC-DSS functions return a status flag to indicate a successful operation or not. Generally, a return status of 0 (zero, or STATUS_OKAY) indicates a successful operation. A status of -1 (minus one, or STATUS_NOT_OKAY) usually indicates that operation could not be preformed because the record to operate on was not found or similar. DSS does not consider this an "error", just an operation that could not be preformed.
A return status of less than 0 (actually a large negative number) indicates an error, and information about that error is encoded in the status. When such an error is encountered, the calling program needs to take an appropriate action.
The error code will have the format as follows:
-a bb cc dd ee
Where:
- "a" (0–9) indicates the error severity, with 9 being the highest
- "bb" (0-99) indicates the highest function called when the error occurred (e.g., ztsStore)
- "cc" (0-99) indicates the function where the error actually occurred (e.g., zput)
- "dd" (0-99) is the actual error
- "ee" (0-99) is the system error code, if the error was returned by the OS
Upon receiving an error, the function
DSSErrorMessage errorMessage = dataManager.getLastError();
Can be called to decode and provide information about the error. This call should be made immediately after the error was detected and the appropriate action should be taken. After this call has been made, call dataManager.clearError() to record any future errors.
This information is returned in readable form in the object DSSErrorMessage, along with other relevant information, such as the pathname, any addresses used, etc. Generally, the messages will help the user determine what the issue was and how to resolve it, and the severity will indicate to the program what action to take.
To check if an error occurred, either check for a negative status return from a function, or call HecDataManager checkForError(), which will return zero if no error has occurred or the single digit postivie severity of the last error.
HecDataManager public int checkForError() // Returns 0 or + severity
The severity levels and apporopriate actions are as follows:
Severity Level | Value | Meaning | Example | Action |
INFORMATION | 1 | An inconsequential action failed | Unable to unlock a record | None |
WARNING | 2 | Unable to compete the request given | Pathname does not exist | Cannot complete the request given (e.g., data was not read) |
INVALID_ARGUMENT | 3 | An incorrect argument was passed to a function | No pathname provided | Inform user and have them change |
WARNING_NO_WRITE_ACCESS | 4 | You cannot write to the file | You do not have write permission | Inform user and have them change |
WARNING_NO_FILE_ACCESS | 5 | You cannot read or write to the file | Do not have permission | Inform user and have them change |
WRITE_ERROR | 6 | An error was thrown on a write action. | out of disk space | Do not attempt to access the DSS file |
READ_ERROR | 7 | An error was thrown on a read action. The file maybe damaged. It might be recovered by a squeeze, at the user's discretion. | The file maybe damaged. | It might be recovered by a squeeze, at the user's discretion. |
CORRUPT_FILE | 8 | Flags and pointers are not correct, indicating that something has changed the file outside of DSS | Bad ftp transfer or truncated file | Do not attempt to access the DSS file |
MEMORY_ERROR | 9 | Memory exhausted or flags and pointers in memory are not correct | Array out of bounds | Exit, if program did not crash. |
HEC-DSS error functions include:
• int severity = dataManager.checkForError();
• DSSErrorMessage errorMessage = dataManager.getLastError();
• void dataManager.clearError();
• void dataManager.clearSevereError(boolean reopenFile);
These functions are for errors from the native DSS library. The Java code has its standard error handling proceedures, which generally use a "try, catch" block. Both errors from Java and from the DSS library need to be handled. For example, if you try to access a DSS file on a disk that does not exsit, the Java code will throw an exception before the DSS library is called.
The correct way to open a DSS file with appropriate error handling is as follows:
HecDataManager dataManager = new HecDataManager();
try {
dataManager.setDSSFileName(filename);
if (dataManager.checkForError() != 0) {
if (processError(dataManager)) return;
}
}
catch (Exception except) {
if (processError(except)) return;
}
The checkForError() call can be made after the catch instead, if preferred.
Example: Simple Error Processing
Example: Simple Error Processing
import javax.swing.UIManager;
import hec.heclib.dss.*;
import hec.io.TimeSeriesContainer;
public class ExampleSimpleErrorProcessing {
public static void main (String args[]) {
try {
javax.swing.UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch (Exception ignore) {}
HecTimeSeries dataManager = new HecTimeSeries();
String filename = "C:/temp/Sample7.dss";
try {
dataManager.open(filename, false, 7);
if (dataManager.checkForError() != 0) {
DSSErrorMessage errorMessage = dataManager.getLastError();
dataManager.clearError();
if ((errorMessage != null) || (errorMessage.severity > 0)) {
System.out.println(errorMessage.message());
if (errorMessage.severity > 3) return;
}
}
}
catch (Exception except) {
System.out.println(except);
return;
}
try {
// Create an error by trying to write an empty TimeSeriesContainer
int status = dataManager.write(new TimeSeriesContainer());
if (status < 0) {
DSSErrorMessage errorMessage = dataManager.getLastError();
dataManager.clearError();
System.out.println(errorMessage.message());
if (errorMessage.severity > 3) return;
}
}
catch (Exception except) {
System.out.println(except);
}
HecDataManager.closeAllFiles();
}
}
Example: Error Processing
Example: Error Processing
//You may want to copy portions of this example directly into your program.
import java.io.File;
import java.io.RandomAccessFile;
import javax.swing.JOptionPane;
import javax.swing.UIManager;
import hec.heclib.dss.*;
import hec.io.TimeSeriesContainer;
public class ExampleErrorProcessing {
protected static boolean _showDialog = true;
public static void main (String args[]) {
try {
javax.swing.UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch (Exception ignore) {}
// Try to create a file with an invalid name or location
// This error is caught in the Java code and throws an exception
HecTimeSeries dataManager = new HecTimeSeries();
String filename = "Z:/temp/Sample7.dss";
try {
dataManager.open(filename, false, 7);
if (dataManager.checkForError() != 0) {
if (processError(dataManager)) return;
}
}
catch (Exception except) {
// We will end up here
System.out.println(except);
}
// Create a DSS file, then clobber the file header to create an error
filename = "C:/temp/ExampleErrorProcess.dss";
dataManager = new HecTimeSeries();
try {
File f = new File(filename);
f.delete();
dataManager.open(filename, false, 7);
if (dataManager.checkForError() != 0) {
if (processError(dataManager)) return;
}
dataManager.close();
RandomAccessFile raf = new RandomAccessFile(filename, "rw");
raf.seek(10);
raf.writeChars("Im a string that is clobbering this DSS file.");
raf.close();
dataManager.open(filename, false, 7);
if (dataManager.checkForError() != 0) {
// We will end up here
if (processError(dataManager)) return;
}
}
catch (Exception except) {
System.out.println(except);
}
// Delete it and make it a valid file, then
// Try to write a time series data set with nothing in it
try {
File f = new File(filename);
f.delete();
dataManager.setDSSFileName(filename, false, 7);
if (dataManager.checkForError() != 0) {
if (processError(dataManager)) return;
}
int status = dataManager.write(new TimeSeriesContainer());
if (dataManager.checkForError() != 0) {
if (processError(dataManager)) return;
}
}
catch (Exception except) {
System.out.println(except);
}
HecDataManager.closeAllFiles();
System.out.println("Completed Example");
}
public static boolean processError(HecDataManager dataManager)
{
if (dataManager == null) {
String message = "Unknown Error / Unable to access file";
System.out.println(message.toString());
if (_showDialog) {
JOptionPane.showMessageDialog(null, message,
" Critical Error",
JOptionPane.ERROR_MESSAGE);
}
return false;
}
DSSErrorMessage errorMessage = dataManager.getLastError();
dataManager.clearError();
if ((errorMessage == null) || (errorMessage.errorType == 0)) {
return false;
}
// An error has occurred, get message
StringBuffer message = new StringBuffer();
if (errorMessage.errorType < 3) {
buildErrorMessage(message, errorMessage, _showDialog);
return true;
}
else {
buildErrorMessage(message, errorMessage, false);
message.append("\nProgram must exit.\nPress OK to exit or Cancel to attempt to continue.");
System.out.println(message.toString());
if (_showDialog) {
int option = JOptionPane.showConfirmDialog(null, message.toString(),
"Critical Error",
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.ERROR_MESSAGE);
if (option == JOptionPane.CANCEL_OPTION) {
return true;
}
}
// Don't save anything or close anything - just get out
System.exit(-1);
return true;
}
}
public static void buildErrorMessage(StringBuffer message, DSSErrorMessage errorMessage, boolean showDialog)
{
int icon = JOptionPane.INFORMATION_MESSAGE;
if (errorMessage.errorType == 1) {
message.append("Warning:\n");
icon = JOptionPane.WARNING_MESSAGE;
}
else if (errorMessage.errorType == 2) {
message.append("File access error:\n");
icon = JOptionPane.WARNING_MESSAGE;
}
else if (errorMessage.errorType == 3) {
message.append("File corruption error:\n");
icon = JOptionPane.ERROR_MESSAGE;
}
else if (errorMessage.errorType == 4) {
message.append("Critical error:\n");
icon = JOptionPane.ERROR_MESSAGE;
}
if (errorMessage.errorMessage.trim().length() > 2) {
message.append(errorMessage.errorMessage);
}
if (errorMessage.systemErrorMessage.trim().length() > 2) {
message.append("\nSystem message: ");
message.append(errorMessage.systemErrorMessage.trim());
}
if (errorMessage.systemError > 0) {
message.append("\nSystem error code: ");
message.append(errorMessage.systemError);
}
if (errorMessage.lastPathname.trim().length() > 2) {
message.append("\nPathname: ");
message.append(errorMessage.lastPathname);
}
if (errorMessage.dssFileName.trim().length() > 2) {
message.append("\nFile: ");
message.append(errorMessage.dssFileName);
}
message.append("\nSeverity: ");
message.append(errorMessage.severity);
if (errorMessage.errorType >= 1) {
if (errorMessage.functionName.trim().length() > 2) {
message.append("\nError occurred in function: ");
message.append(errorMessage.functionName);
if (errorMessage.calledByFunction.trim().length() > 2) {
message.append("\nCalled by function: ");
message.append(errorMessage.calledByFunction);
}
}
if (errorMessage.lastAddress > 0) {
message.append("\nat address: ");
message.append(errorMessage.lastAddress);
}
}
// message.append("\nError Code: ");
// message.append(errorMessage.errorCode);
System.out.println(message.toString());
if (showDialog) {
JOptionPane.showMessageDialog(null, message.toString(),
" Error", icon);
}
}
}
Output:
Cannot access DSS file *****
DSS file name given: Z:/temp/Sample7.dss
java.io.IOException: The system cannot find the path specified
Absolute DSS file name: Z:\temp\Sample7.dss
Exception: The system cannot find the path specified
at java.io.WinNTFileSystem.createFileExclusively(Native Method)
at java.io.File.createNewFile(File.java:1012)
at hec.heclib.dss.HecDSSFileAccess.setDSSFileName(HecDSSFileAccess.java:433)
at hec.heclib.dss.HecDSSFileAccess.open(HecDSSFileAccess.java:463)
at ExampleErrorProcessing.main(ExampleErrorProcessing.java:26)
Cannot open data base file: C:\temp\ExampleErrorProcess.dss
- Error - Unable to access HEC-DSS file: C:\temp\ExampleErrorProcess.dss
File corruption error:
****DSS** ERROR in function zopen: The DSS file main header is damaged.
An invalid number was read from the file: 0
Squeeze the file to attempt recovery.
Invalid DSS file version string
Severity: 8
Error occurred in function: zopen
File corruption error:
****DSS** ERROR in function zopen: The DSS file main header is damaged.
An invalid number was read from the file: 0
Squeeze the file to attempt recovery.
Invalid DSS file version string
Severity: 8
Error occurred in function: zopen
Program must exit.
Press OK to exit or Cancel to attempt to continue.
- Error - Unable to access HEC-DSS file: C:\temp\ExampleErrorProcess.dss