/*------------------------------------------------------------------------- * Function: error_stack * * Purpose: Manipulates current error stack. * * Return: Success: 0 * * Failure: -1 * * Programmer: Raymond Lu * July 14, 2003 * *------------------------------------------------------------------------- */ static herr_t error_stack(void) { int err_num; const char *FUNC_error_stack = "error_stack"; if((err_num = H5Eget_num(H5E_DEFAULT)) < 0) TEST_ERROR; if(err_num) TEST_ERROR; if((ERR_STACK = H5Eget_current_stack()) < 0) TEST_ERROR; /* Make it push error, force this function to fail */ if((err_num = H5Eget_num(ERR_STACK)) == 0) { H5Epush(ERR_STACK, __FILE__, FUNC_error_stack, __LINE__, ERR_CLS, ERR_MAJ_API, ERR_MIN_GETNUM, "Get number test failed, returned %d", err_num); goto error; } /* end if */ /* In case program falls through here, close the stack and let it fail. */ if(H5Eclose_stack(ERR_STACK) < 0) TEST_ERROR; return -1; error: return -1; } /* end error_stack() */
/*------------------------------------------------------------------------- * Function: test_copy * * Purpose: Test copyinging an error stack * * Return: Success: 0 * Failure: -1 * * Programmer: Allen Byrne * February 18, 2010 * *------------------------------------------------------------------------- */ static herr_t test_copy(void) { const char *err_func = "test_copy"; /* Function name for pushing error */ const char *err_msg = "Error message"; /* Error message for pushing error */ int err_num; /* Number of errors on stack */ hid_t estack_id; /* Error stack ID */ herr_t ret; /* Generic return value */ /* Push an error with a long description */ if(H5Epush(H5E_DEFAULT, __FILE__, err_func, __LINE__, ERR_CLS, ERR_MAJ_TEST, ERR_MIN_SUBROUTINE, err_msg) < 0) TEST_ERROR; /* Check the number of errors on stack */ err_num = H5Eget_num(H5E_DEFAULT); if(err_num != 1) TEST_ERROR /* Copy error stack, which clears the original */ if((estack_id = H5Eget_current_stack()) < 0) TEST_ERROR /* Check the number of errors on stack copy */ err_num = H5Eget_num(estack_id); if(err_num != 1) TEST_ERROR /* Check the number of errors on original stack */ err_num = H5Eget_num(H5E_DEFAULT); if(err_num != 0) TEST_ERROR /* Put the stack copy as the default. It closes the stack copy, too. */ if(H5Eset_current_stack(estack_id) < 0) TEST_ERROR /* Check the number of errors on default stack */ err_num = H5Eget_num(H5E_DEFAULT); if(err_num != 1) TEST_ERROR /* Try to close error stack copy. Should fail because * the current H5Eset_current_stack closes the stack to be set.*/ H5E_BEGIN_TRY { ret = H5Eclose_stack(estack_id); } H5E_END_TRY if(ret >= 0) TEST_ERROR return(0); error: return(-1); } /* end test_copy() */
Exception::Exception() noexcept { // FIXME: is this the best approach? Is it thread-safe? hid_t stack{H5Eget_current_stack()}; // Pop all but inner-most frame, i.e., the root cause. H5Epop(stack, H5Eget_num(stack) - 1); // Get inner-most error message. H5Ewalk2(stack, H5E_WALK_DOWNWARD, setError, what_); // Free stack. H5Eclose_stack(stack); }
/** * Check the HDF5 error stack and throw Exception with a useful error * message if there are errors on the stack. In theory this can be * used as the auto handler, but that's a C function and we can't * throw exceptions back up to the caller. */ static herr_t auto_throw(hid_t estack, void*) { H5E_error_t err; if (H5Eget_num(estack)<=0) return 0; if (H5Ewalk(estack, H5E_WALK_DOWNWARD, walk_cb, &err) < 0) throw Exception("Failed to walk error stack"); if (err.desc) throw Exception(err.desc); else throw Exception("Failed to extract detailed error description"); return 0; }
/*------------------------------------------------------------------------- * Function: test_create * * Purpose: Test creating an empty error stack * * Return: Success: 0 * Failure: -1 * * Programmer: Quincey Koziol * November 1, 2007 * *------------------------------------------------------------------------- */ static herr_t test_create(void) { const char *err_func = "test_create"; /* Function name for pushing error */ const char *err_msg = "Error message"; /* Error message for pushing error */ int err_num; /* Number of errors on stack */ hid_t estack_id; /* Error stack ID */ /* Create an empty error stack */ if((estack_id = H5Ecreate_stack()) < 0) TEST_ERROR /* Check the number of errors on stack */ err_num = H5Eget_num(estack_id); if(err_num != 0) TEST_ERROR /* Push an error with a long description */ if(H5Epush(estack_id, __FILE__, err_func, __LINE__, ERR_CLS, ERR_MAJ_TEST, ERR_MIN_SUBROUTINE, err_msg) < 0) TEST_ERROR; /* Check the number of errors on stack */ err_num = H5Eget_num(estack_id); if(err_num != 1) TEST_ERROR /* Clear the error stack */ if(H5Eclear2(estack_id) < 0) TEST_ERROR /* Check the number of errors on stack */ err_num = H5Eget_num(estack_id); if(err_num != 0) TEST_ERROR /* Close error stack */ if(H5Eclose_stack(estack_id) < 0) TEST_ERROR return(0); error: return(-1); } /* end test_create() */
/* * Class: hdf_hdf5lib_H5 * Method: H5Eget_num * Signature: (J)J */ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5_H5Eget_1num (JNIEnv *env, jclass cls, jlong stk_id) { ssize_t ret_val = -1; if (stk_id < 0) { h5badArgument(env, "H5Eget_num: invalid argument"); } /* end if */ else { ret_val = H5Eget_num((hid_t)stk_id); if (ret_val < 0) h5libraryError(env); } /* end else */ return (jlong)ret_val; } /* end Java_hdf_hdf5lib_H5_H5Eget_1num */