[MOAB-dev] commit/MOAB: 4 new changesets

commits-noreply at bitbucket.org commits-noreply at bitbucket.org
Mon Jul 14 10:31:33 CDT 2014


4 new commits in MOAB:

https://bitbucket.org/fathomteam/moab/commits/77a70ae7a5bf/
Changeset:   77a70ae7a5bf
Branch:      None
User:        danwu
Date:        2014-07-14 17:30:24
Summary:     Framework code for enhanced error handling.

Affected #:  6 files

diff --git a/src/ErrorHandler.cpp b/src/ErrorHandler.cpp
new file mode 100644
index 0000000..9f0fdee
--- /dev/null
+++ b/src/ErrorHandler.cpp
@@ -0,0 +1,75 @@
+#include "moab/ErrorHandler.hpp"
+#include "ErrorOutput.hpp"
+#ifdef USE_MPI
+#include "moab_mpi.h"
+#endif
+
+#include <stdlib.h>
+
+namespace moab {
+
+static ErrorOutput* errorOutput = NULL;
+
+void MBErrorHandler_Init()
+{
+  if (NULL == errorOutput) {
+    errorOutput = new ErrorOutput(stderr);
+    errorOutput->use_world_rank();
+  }
+}
+
+void MBErrorHandler_Finalize()
+{
+  if (NULL != errorOutput) {
+    delete errorOutput;
+    errorOutput = NULL;
+  }
+}
+
+bool MBErrorHandler_Initialized()
+{
+  return (NULL != errorOutput);
+}
+
+void MBTraceBackErrorHandler(int line, const char* func, const char* file, const char* dir, const char* err_msg, ErrorType err_type)
+{
+  // For a globally fatal error, get world rank of current processor, so that it is only printed from processor 0
+  // For a per-processor relevant error, set rank of current processor to 0, so that it is always printed
+  int rank = 0;
+  if (MB_ERROR_TYPE_NEW_GLOBAL == err_type && NULL != errorOutput && errorOutput->have_rank())
+    rank = errorOutput->get_rank();
+
+  if (0 == rank) {
+    // Print the error messages if it is a new error
+    if (MB_ERROR_TYPE_EXISTING != err_type && NULL != errorOutput && NULL != err_msg) {
+      errorOutput->print("--------------------- Error Message ------------------------------------\n");
+      errorOutput->printf("%s!\n", err_msg);
+    }
+
+    // Print a line of stack trace
+    if (NULL != errorOutput)
+      errorOutput->printf("%s() line %d in %s%s\n", func, line, dir, file);
+  }
+  else {
+    // Do not print the error messages, since processor 0 will print them
+    // Sleep 10 seconds before aborting so it will not accidently kill process 0
+    sleep(10);
+    abort();
+  }
+}
+
+ErrorCode MBError(int line, const char* func, const char* file, const char* dir, ErrorCode err_code, const char* err_msg, ErrorType err_type)
+{
+  MBTraceBackErrorHandler(line, func, file, dir, err_msg, err_type);
+
+#ifdef USE_MPI
+  // If this is called from the main() routine we call MPI_Abort() to allow
+  // the parallel program to be properly shutdown
+  if (strncmp(func, "main", 4) == 0)
+    MPI_Abort(MPI_COMM_WORLD, err_code);
+#endif
+
+  return err_code;
+}
+
+} // namespace moab

diff --git a/src/ErrorOutput.cpp b/src/ErrorOutput.cpp
new file mode 100644
index 0000000..e71e010
--- /dev/null
+++ b/src/ErrorOutput.cpp
@@ -0,0 +1,169 @@
+#include "ErrorOutput.hpp"
+
+#include <iostream>
+#include <string.h>
+#include <algorithm>
+#include <assert.h>
+
+#ifdef USE_MPI
+#include "moab_mpi.h"
+#endif
+
+namespace moab {
+
+class FILEErrorStream : public ErrorOutputStream
+{
+private:
+  FILE* filePtr;
+
+public:
+  FILEErrorStream(FILE* filep) : filePtr(filep) {}
+  void println(int rank, const char* str);
+  void println(const char* str);
+};
+
+void FILEErrorStream::println(int rank, const char* str)
+{
+  fprintf(filePtr, "[%d]MOAB ERROR: %s\n", rank, str);
+  fflush(filePtr);
+}
+
+void FILEErrorStream::println(const char* str)
+{
+  fprintf(filePtr, "MOAB ERROR: %s\n", str);
+  fflush(filePtr);
+}
+
+class CxxErrorStream : public ErrorOutputStream
+{
+private:
+  std::ostream& outStr;
+
+public:
+  CxxErrorStream(std::ostream& str) : outStr(str) {}
+  void println(int rank, const char* str);
+  void println(const char* str);
+};
+
+void CxxErrorStream::println(int rank, const char* str)
+{
+  outStr << "[" << rank << "]MOAB ERROR: "  << str << std::endl;
+  outStr.flush();
+}
+
+void CxxErrorStream::println(const char* str)
+{
+  outStr << "MOAB ERROR: " << str << std::endl;
+  outStr.flush();
+}
+
+ErrorOutput::ErrorOutput(FILE* impl)
+  : outputImpl(new FILEErrorStream(impl)),
+    mpiRank(-1)
+{
+  lineBuffer.reserve(1024);
+}
+
+ErrorOutput::ErrorOutput(std::ostream& str)
+  : outputImpl(new CxxErrorStream(str)),
+    mpiRank(-1)
+{
+  lineBuffer.reserve(1024);
+}
+
+ErrorOutput::~ErrorOutput()
+{ 
+  if (!lineBuffer.empty()) {
+    lineBuffer.push_back('\n');
+    process_line_buffer();
+  }
+
+  if (NULL != outputImpl) {
+    delete outputImpl;
+    outputImpl = NULL;
+  }
+}
+
+void ErrorOutput::use_world_rank()
+{
+#ifdef USE_MPI
+    int flag1;
+    MPI_Initialized(&flag1);
+    int flag2;
+    MPI_Finalized(&flag2);
+    if (flag1 && !flag2)
+      MPI_Comm_rank(MPI_COMM_WORLD, &mpiRank);
+#endif
+}
+
+void ErrorOutput::print_real(const char* buffer)
+{
+  lineBuffer.insert(lineBuffer.end(), buffer, buffer + strlen(buffer));
+  process_line_buffer();
+}
+
+void ErrorOutput::print_real(const std::string& str)
+{
+  lineBuffer.insert(lineBuffer.end(), str.begin(), str.end());
+  process_line_buffer();
+}
+
+void ErrorOutput::print_real(const char* fmt, va_list args1, va_list args2)
+{
+  size_t idx = lineBuffer.size();
+#ifdef HAVE_VSNPRINTF
+  // try once with remaining space in buffer
+  lineBuffer.resize(lineBuffer.capacity());
+  unsigned size = vsnprintf(&lineBuffer[idx], lineBuffer.size() - idx, fmt, args1);
+  ++size; // trailing null
+  // if necessary, increase buffer size and retry
+  if (size > (lineBuffer.size() - idx)) {
+    lineBuffer.resize(idx + size);
+    size = vsnprintf(&lineBuffer[idx], lineBuffer.size() - idx, fmt, args2);
+    ++size; // trailing null
+  }
+#else
+  // Guess how much space might be required.
+  // If every character is a format code then there are len/3 format codes.
+  // Guess a random large value of 81 characters per formatted argument.
+  unsigned exp_size = 27 * strlen(fmt);
+  lineBuffer.resize(idx + exp_size);
+  unsigned size = vsprintf(&lineBuffer[idx], fmt, args1);
+  ++size; // trailing null
+  // check if we overflowed the buffer
+  if (size > exp_size) {
+    // crap!
+    fprintf(stderr, "ERROR: Buffer overflow at %s:%d\n", __FILE__, __LINE__);
+    lineBuffer.resize(idx + exp_size);
+    size = vsprintf(&lineBuffer[idx], fmt, args2);
+    ++size; // trailing null
+  }
+#endif
+
+  // less one because we don't want the trailing '\0'
+  lineBuffer.resize(idx + size - 1);
+  process_line_buffer();
+}
+
+void ErrorOutput::process_line_buffer()
+{
+  size_t last_idx = 0;
+  std::vector<char>::iterator i;
+  for (i = std::find(lineBuffer.begin(), lineBuffer.end(), '\n');
+       i != lineBuffer.end(); i = std::find(i, lineBuffer.end(), '\n')) {
+    *i = '\0';
+    if (have_rank())
+      outputImpl->println(get_rank(), &lineBuffer[last_idx]);
+    else
+      outputImpl->println(&lineBuffer[last_idx]);
+    ++i;
+    last_idx = i - lineBuffer.begin();
+  }
+
+  if (last_idx) {
+    i = std::copy(lineBuffer.begin() + last_idx, lineBuffer.end(), lineBuffer.begin());
+    lineBuffer.erase(i, lineBuffer.end());
+  }
+}
+
+} // namespace moab

diff --git a/src/ErrorOutput.hpp b/src/ErrorOutput.hpp
new file mode 100644
index 0000000..cd9a03e
--- /dev/null
+++ b/src/ErrorOutput.hpp
@@ -0,0 +1,101 @@
+#ifndef moab_ERROR_OUTPUT_HPP
+#define moab_ERROR_OUTPUT_HPP
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <vector>
+#include <iosfwd>
+#include <string>
+
+#include "moab/Compiler.hpp"
+
+namespace moab {
+
+class ErrorOutputStream;
+
+/**\brief Utility class for printing error output
+ *
+ * This class implements line-oriented output. That is, it buffers
+ * output data until a newline is encountered, at which point it
+ * sends the output to the output stream followed by an explicit
+ * flush, and optionally prefixed with the MPI rank.
+ *
+ * \Note Any output not terminated with an newline character or
+ *       followed by later output containing a newline character
+ *       will not be flushed until the destructor is invoked.
+ */
+class ErrorOutput {
+public:
+  /**
+   *\param str       Output stream to which to flush output
+   */
+  ErrorOutput(FILE* str);
+
+  /**
+   *\param str       Output stream to which to flush output
+   */
+  ErrorOutput(std::ostream& str);
+
+  /**
+   * Destructor flushes any remaining output that wasn't followed
+   * by a newline character.
+   */
+  ~ErrorOutput();
+
+  //!\brief Check if MPI rank has been set.
+  bool have_rank() const { return mpiRank >= 0; }
+  //!\brief Get MPI rank.
+  int get_rank() const { return mpiRank; }
+  //!\brief Set MPI rank.
+  void set_rank(int rank) { mpiRank = rank; }
+  //!\brief Set MPI rank to the rank of this process in MPI_COMM_WORLD,
+  //!       if MOAB is built with MPI and MPI_Init has been called
+  void use_world_rank();
+
+  //!\brief Output the specified string
+  void print(const char* str) { print_real(str); }
+
+  //!\brief Output the specified string
+  void print(const std::string& str) { print_real(str); }
+
+  //!\brief Output the specified printf-formatted output
+  void printf(const char* fmt, ...) MB_PRINTF(1);
+
+private:
+  ErrorOutputStream* outputImpl;
+  int mpiRank;
+
+  void print_real(const char* buffer);
+  void print_real(const std::string& str);
+
+  // Function must be passed to copies of the same va_list because
+  // a) it might have to call vs(n)printf twice, b) vs(n)printf modifies
+  // the va_list such that it cannot be reused, and c) va_copy is not
+  // (yet) portable (c99, no c++ standard).
+  void print_real(const char* buffer, va_list args1, va_list args2);
+  void process_line_buffer();
+
+  std::vector<char> lineBuffer;
+};
+
+inline void ErrorOutput::printf(const char* fmt, ...)
+{
+  va_list args1, args2;
+  va_start(args1, fmt);
+  va_start(args2, fmt);
+  print_real(fmt, args1, args2);
+  va_end(args2);
+  va_end(args1);
+}
+
+class ErrorOutputStream {
+public:
+  ErrorOutputStream() {}
+  virtual ~ErrorOutputStream() {}
+  virtual void println(const char* str) = 0;
+  virtual void println(int rank, const char* str) = 0;
+};
+
+} // namespace moab
+
+#endif

diff --git a/src/Makefile.am b/src/Makefile.am
index a9adf0d..f55d82c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -56,6 +56,9 @@ libMOAB_la_SOURCES = \
   ElementSequence.hpp \
   EntitySequence.cpp \
   EntitySequence.hpp \
+  ErrorHandler.cpp \
+  ErrorOutput.cpp \
+  ErrorOutput.hpp \
   Factory.cpp \
   FBEngine.cpp \
   FileOptions.cpp \
@@ -161,6 +164,7 @@ nobase_libMOAB_la_include_HEADERS = \
   moab/HomXform.hpp \
   moab/EntityType.hpp \
   moab/EntityHandle.hpp \
+  moab/ErrorHandler.hpp \
   moab/FBEngine.hpp \
   moab/FileOptions.hpp \
   moab/FindPtFuncs.h \

diff --git a/src/moab/ErrorHandler.hpp b/src/moab/ErrorHandler.hpp
new file mode 100644
index 0000000..ec91113
--- /dev/null
+++ b/src/moab/ErrorHandler.hpp
@@ -0,0 +1,144 @@
+#ifndef MOAB_ERROR_HANDLER_HPP
+#define MOAB_ERROR_HANDLER_HPP
+
+#include "moab/Types.hpp"
+
+#include <sstream>
+#include <string.h>
+
+namespace moab {
+
+//! ErrorType - passed to the error handling routines indicating if this is a new error (globally fatal
+//! or per-processor relevant) or an existing one
+enum ErrorType {MB_ERROR_TYPE_NEW_GLOBAL = 0, MB_ERROR_TYPE_NEW_LOCAL = 1, MB_ERROR_TYPE_EXISTING = 2};
+
+//! Initialize MOAB error handler (e.g. create a utility object for printing error output)
+void MBErrorHandler_Init();
+
+//! Finalize MOAB error handler (e.g. delete the utility object for printing error output)
+void MBErrorHandler_Finalize();
+
+//! Indicates whether MBErrorHandler_Init has been called
+bool MBErrorHandler_Initialized();
+
+//! Routine that is called when an error has been detected
+ErrorCode MBError(int line, const char* func, const char* file, const char* dir,
+                  ErrorCode err_code, const char* err_msg, ErrorType err_type);
+
+#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
+
+#define MBSTRINGIFY_(X) #X
+#define MBSTRINGIFY(X) MBSTRINGIFY_(X)
+
+#ifdef LOCDIR
+#define __SDIR__ MBSTRINGIFY(LOCDIR)
+#else
+#define __SDIR__ ""
+#endif
+
+//! Set a new error with passed error code and passed error message string
+#define SET_ERR(err_code, err_msg) \
+  return MBError(__LINE__, __func__, __FILENAME__, __SDIR__, err_code, err_msg, MB_ERROR_TYPE_NEW_LOCAL)
+
+//! Set a new error with passed error code and passed error message string stream
+#define SET_ERR_STR(err_code, err_msg_str) \
+  do { \
+    std::ostringstream ostr; \
+    ostr << err_msg_str; \
+    return MBError(__LINE__, __func__, __FILENAME__, __SDIR__, err_code, ostr.str().c_str(), MB_ERROR_TYPE_NEW_LOCAL); \
+  } while (false)
+
+//! Set a new global error with passed error code and passed error message string
+#define SET_GLB_ERR(err_code, err_msg) \
+  return MBError(__LINE__, __func__, __FILENAME__, __SDIR__, err_code, err_msg, MB_ERROR_TYPE_NEW_GLOBAL)
+
+//! Set a new global error with passed error code and passed error message string stream
+#define SET_GLB_ERR_STR(err_code, err_msg_str) \
+  do { \
+    std::ostringstream ostr; \
+    ostr << err_msg_str; \
+    return MBError(__LINE__, __func__, __FILENAME__, __SDIR__, err_code, ostr.str().c_str(), MB_ERROR_TYPE_NEW_GLOBAL); \
+  } while (false)
+
+//! Check returned error code against MB_SUCCESS
+#define CHK_ERR(err_code) \
+  do { \
+    if (MB_SUCCESS != err_code) \
+      return MBError(__LINE__, __func__, __FILENAME__, __SDIR__, err_code, "", MB_ERROR_TYPE_EXISTING); \
+  } while (false)
+
+//! Check returned error code against MB_SUCCESS
+//! Set a new error with the returned error code and passed error message string
+#define CHK_ERR1(err_code, err_msg_to_set) \
+  do { \
+    if (MB_SUCCESS != err_code) \
+      SET_ERR(err_code, err_msg_to_set); \
+  } while (false)
+
+//! Check returned error code against MB_SUCCESS
+//! Set a new error with the returned error code and passed error message string stream
+#define CHK_ERR1_STR(err_code, err_msg_str_to_set) \
+  do { \
+    if (MB_SUCCESS != err_code) \
+      SET_ERR_STR(err_code, err_msg_str_to_set); \
+  } while (false)
+
+//! Check returned error code against MB_SUCCESS
+//! Set a new error with passed error code and passed error message string
+#define CHK_ERR2(err_code, err_code_to_set, err_msg_to_set) \
+  do { \
+    if (MB_SUCCESS != err_code) \
+      SET_ERR(err_code_to_set, err_msg_to_set); \
+  } while (false)
+
+//! Check returned error code against MB_SUCCESS
+//! Set a new error with passed error code and passed error message string stream
+#define CHK_ERR2_STR(err_code, err_code_to_set, err_msg_str_to_set) \
+  do { \
+    if (MB_SUCCESS != err_code) \
+      SET_ERR_STR(err_code_to_set, err_msg_str_to_set); \
+  } while (false)
+
+//! Check returned error code against an expected one
+//! Set a new error with default error code and default error message string
+#define CHK_EQL(err_code, exp_err_code) \
+  do { \
+    if (exp_err_code != err_code) \
+      SET_ERR(MB_FAILURE, "Returned error code is not expected"); \
+  } while (false)
+
+//! Check returned error code against an expected one
+//! Set a new error with default error code and passed error message string
+#define CHK_EQL1(err_code, exp_err_code, err_msg_to_set) \
+  do { \
+    if (exp_err_code != err_code) { \
+      SET_ERR(MB_FAILURE, err_msg_to_set); \
+    } \
+  } while (false)
+
+//! Check returned error code against an expected one
+//! Set a new error with default error code and passed error message string stream
+#define CHK_EQL1_STR(err_code, exp_err_code, err_msg_str_to_set) \
+  do { \
+    if (exp_err_code != err_code) \
+      SET_ERR_STR(MB_FAILURE, err_msg_str_to_set); \
+  } while (false)
+
+//! Check returned error code against an expected one
+//! Set a new error with passed error code and passed error message string
+#define CHK_EQL2(err_code, exp_err_code, err_code_to_set, err_msg_to_set) \
+  do { \
+    if (exp_err_code != err_code) \
+      SET_ERR(err_code_to_set, err_msg_to_set); \
+  } while (false)
+
+//! Check returned error code against an expected one
+//! Set a new error with passed error code and passed error message string stream
+#define CHK_EQL2_STR(err_code, exp_err_code, err_code_to_set, err_msg_str_to_set) \
+  do { \
+    if (exp_err_code != err_code) \
+      SET_ERR_STR(err_code_to_set, err_msg_str_to_set); \
+  } while (false)
+#endif
+
+} // namespace moab

diff --git a/src/moab/Interface.hpp b/src/moab/Interface.hpp
index 09f4219..8ffe2a3 100644
--- a/src/moab/Interface.hpp
+++ b/src/moab/Interface.hpp
@@ -43,6 +43,7 @@
 #include "moab/Forward.hpp"
 #include "moab/Range.hpp"
 #include "moab/Compiler.hpp"
+#include "moab/ErrorHandler.hpp"
 
 // include files
 #include <string>


https://bitbucket.org/fathomteam/moab/commits/ac408a159b79/
Changeset:   ac408a159b79
Branch:      None
User:        danwu
Date:        2014-07-14 17:30:24
Summary:     Adding example to simulate MOAB's enhanced error handling in parallel. All of the errors are contrived, used for simulation purpose only.

Affected #:  2 files

diff --git a/examples/ErrorHandlingSimulation.cpp b/examples/ErrorHandlingSimulation.cpp
new file mode 100644
index 0000000..ffdc831
--- /dev/null
+++ b/examples/ErrorHandlingSimulation.cpp
@@ -0,0 +1,100 @@
+/** @example ErrorHandlingSimulation.cpp
+ * Description: This example simulates MOAB's enhanced error handling in parallel. \n
+ * All of the errors are contrived, used for simulation purpose only. \n
+ *
+ * <b>To run</b>: mpiexec -np 4 ./ErrorHandlingSimulation <test_case_num(1 to 4)> \n
+ */
+
+#include "moab/ErrorHandler.hpp"
+#ifdef USE_MPI
+#include "moab_mpi.h"
+#endif
+
+#include <iostream>
+#include <stdlib.h>
+
+using namespace moab;
+using namespace std;
+
+// Functions that create and handle contrived errors
+// Call hierarchy: A calls B, and B calls C
+ErrorCode FunctionC(int test_case_num, int rank)
+{
+  switch (test_case_num) {
+    case 1:
+      // Simulate a global fatal error MB_NOT_IMPLEMENTED on all processors
+      // Note, it is printed by root processor 0 only
+      SET_GLB_ERR(MB_NOT_IMPLEMENTED, "A contrived global error MB_NOT_IMPLEMENTED");
+      break;
+    case 2:
+      // Simulate a per-processor relevant error MB_INDEX_OUT_OF_RANGE on all processors
+      // Note, it is printed by all processors
+      SET_ERR_STR(MB_INDEX_OUT_OF_RANGE, "A contrived error MB_INDEX_OUT_OF_RANGE on processor " << rank);
+      break;
+    case 3:
+      // Simulate a per-processor relevant error MB_TYPE_OUT_OF_RANGE on all processors except root
+      // Note, it is printed by all non-root processors
+      if (0 != rank)
+        SET_ERR_STR(MB_TYPE_OUT_OF_RANGE, "A contrived error MB_TYPE_OUT_OF_RANGE on processor " << rank);
+      break;
+    case 4:
+      // Simulate a per-processor relevant error MB_INDEX_OUT_OF_RANGE on processor 1
+      // Note, it is printed by processor 1 only
+      if (1 == rank)
+        SET_ERR(MB_INDEX_OUT_OF_RANGE, "A contrived error MB_INDEX_OUT_OF_RANGE on processor 1");
+
+      // Simulate a per-processor relevant error MB_TYPE_OUT_OF_RANGE on processor 3
+      // Note, it is printed by processor 3 only
+      if (3 == rank)
+        SET_ERR(MB_TYPE_OUT_OF_RANGE, "A contrived error MB_TYPE_OUT_OF_RANGE on processor 3");
+      break;
+    default:
+      break;
+  }
+
+  return MB_SUCCESS;
+}
+
+ErrorCode FunctionB(int test_case_num, int rank)
+{
+  ErrorCode err_code = FunctionC(test_case_num, rank);CHK_ERR(err_code);
+
+  return MB_SUCCESS;
+}
+
+ErrorCode FunctionA(int test_case_num, int rank)
+{
+  ErrorCode err_code = FunctionB(test_case_num, rank);CHK_ERR(err_code);
+
+  return MB_SUCCESS;
+}
+
+int main(int argc, char** argv)
+{
+  if (argc < 2) {
+    cout << "Usage: " << argv[0] << " <test_case_num(1 to 4)>" << endl;
+    return 0;
+  }
+
+#ifdef USE_MPI
+  MPI_Init(&argc, &argv);
+#endif
+
+  MBErrorHandler_Init();
+
+  int test_case_num = atoi(argv[1]);
+  int rank = 0;
+#ifdef USE_MPI
+  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+#endif
+
+  ErrorCode rval = FunctionA(test_case_num, rank);CHK_ERR(rval);
+
+  MBErrorHandler_Finalize();
+
+#ifdef USE_MPI
+  MPI_Finalize();
+#endif
+
+  return 0;
+}

diff --git a/examples/makefile b/examples/makefile
index 787c8d3..c4dd9e7 100644
--- a/examples/makefile
+++ b/examples/makefile
@@ -11,8 +11,9 @@ EXAMPLES = HelloMOAB GetEntities SetsNTags LoadPartial structuredmesh Structured
 PAREXAMPLES = HelloParMOAB ReduceExchangeTags LloydRelaxation CrystalRouterExample
 EXOIIEXAMPLES = TestExodusII
 F90EXAMPLES = DirectAccessNoHolesF90 PushParMeshIntoMoabF90
+ERROREXAMPLES = ErrorHandlingSimulation
 
-default: ${EXAMPLES} ${PAREXAMPLES} ${EXOIIEXAMPLES} ${F90EXAMPLES}
+default: ${EXAMPLES} ${PAREXAMPLES} ${EXOIIEXAMPLES} ${F90EXAMPLES} ${ERROREXAMPLES}
 
 HelloMOAB: HelloMOAB.o ${MOAB_LIBDIR}/libMOAB.la
 	${MOAB_CXX} -o $@ $< ${MOAB_LIBS_LINK}
@@ -70,9 +71,12 @@ VisTags: VisTags.o ${MOAB_LIBDIR}/libMOAB.la
 
 ReadWriteTest: ReadWriteTest.o ${MOAB_LIBDIR}/libMOAB.la
 	${MOAB_CXX} -o $@ $< ${MOAB_LIBS_LINK} 
-	
+
+ErrorHandlingSimulation: ErrorHandlingSimulation.o ${MOAB_LIBDIR}/libMOAB.la
+	${MOAB_CXX} -o $@ $< ${MOAB_LIBS_LINK}
+
 clean:
-	rm -rf *.o *.mod *.h5m ${EXAMPLES} ${PAREXAMPLES} ${EXOIIEXAMPLES} ${F90EXAMPLES}
+	rm -rf *.o *.mod *.h5m ${EXAMPLES} ${PAREXAMPLES} ${EXOIIEXAMPLES} ${F90EXAMPLES} ${ERROREXAMPLES}
 
 .cpp.o:
 	${MOAB_CXX} ${CXXFLAGS} ${MOAB_CXXFLAGS} ${MOAB_CPPFLAGS} ${MOAB_INCLUDES} -DMESH_DIR=\"${MESH_DIR}\" -c $<


https://bitbucket.org/fathomteam/moab/commits/84ef2def3842/
Changeset:   84ef2def3842
Branch:      None
User:        danwu
Date:        2014-07-14 17:30:24
Summary:     Applied new error handling code to a few places in Core.cpp and ReadParallel.cpp, to test serial or parallel read of climate .nc files (with errors returned) later.

Affected #:  4 files

diff --git a/src/Core.cpp b/src/Core.cpp
index 0bd882f..01b5b9b 100644
--- a/src/Core.cpp
+++ b/src/Core.cpp
@@ -483,6 +483,7 @@ ErrorCode Core::load_file( const char* file_name,
       rval = ReadParallel(this,pcomm).load_file( file_name, file_set, opts, &sl );
     else
       rval = ReadParallel(this,pcomm).load_file( file_name, file_set, opts );
+    CHK_ERR(rval);
 #else
     mError->set_last_error( "PARALLEL option not valid, this instance"
                             " compiled for serial execution.\n" );
@@ -494,6 +495,7 @@ ErrorCode Core::load_file( const char* file_name,
       rval = serial_load_file( file_name, file_set, opts, &sl );
     else
       rval = serial_load_file( file_name, file_set, opts );
+    CHK_ERR(rval);
   }
 
   if (MB_SUCCESS == rval && !opts.all_seen()) {
@@ -544,8 +546,9 @@ ErrorCode Core::serial_load_file( const char* file_name,
   status = stat(file_name, &stat_data);
 #endif
   if (status) {
-    mError->set_last_error( "%s: %s", file_name, strerror(errno) );
-    return MB_FILE_DOES_NOT_EXIST;
+    //mError->set_last_error( "%s: %s", file_name, strerror(errno) );
+    //return MB_FILE_DOES_NOT_EXIST;
+    SET_GLB_ERR_STR(MB_FILE_DOES_NOT_EXIST, file_name << ": " << strerror(errno));
   }
 #if defined(WIN32) || defined(WIN64) || defined(MSC_VER)
   else if (_S_IFDIR(stat_data.st_mode)) {
@@ -608,6 +611,7 @@ ErrorCode Core::serial_load_file( const char* file_name,
 
   if (MB_SUCCESS != rval) {
     clean_up_failed_read( initial_ents, initial_tags );
+    SET_ERR(rval, "Failed to load file after trying all possible readers");
   }
   else if (file_set) {
     Range new_ents;

diff --git a/src/Makefile.am b/src/Makefile.am
index f55d82c..bc3a8de 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -19,6 +19,7 @@ BUILT_SOURCES = MBCN_protos.h
 
 # Some variables
 AM_CPPFLAGS += -DIS_BUILDING_MB \
+               -DLOCDIR=src/ \
                -I. \
                -I$(srcdir)/io \
                -I$(srcdir)/io/mhdf/include \

diff --git a/src/parallel/Makefile.am b/src/parallel/Makefile.am
index b80b85e..5a39552 100644
--- a/src/parallel/Makefile.am
+++ b/src/parallel/Makefile.am
@@ -5,7 +5,7 @@ AUTOMAKE_OPTIONS = foreign
 noinst_LTLIBRARIES = libMOABpar.la
          
 # Some variables
-AM_CPPFLAGS += -DIS_BUILDING_MB -DSRCDIR=$(srcdir) \
+AM_CPPFLAGS += -DIS_BUILDING_MB -DSRCDIR=$(srcdir) -DLOCDIR=src/parallel/ \
                -I$(srcdir)/.. -I.. -I$(srcdir)/../io \
                -I$(srcdir)/../io/mhdf/include 
 

diff --git a/src/parallel/ReadParallel.cpp b/src/parallel/ReadParallel.cpp
index fe4ed55..06faf6d 100644
--- a/src/parallel/ReadParallel.cpp
+++ b/src/parallel/ReadParallel.cpp
@@ -235,6 +235,7 @@ ErrorCode ReadParallel::load_file(const char **file_names,
                    reader_rank, cputime, 
                    resolve_dim, shared_dim,
                    ghost_dim, bridge_dim, num_layers, addl_ents);
+  CHK_ERR(result);
                    
   if (parallel_mode == POPT_BCAST_DELETE && !is_reader)
     opts.mark_all_seen();
@@ -519,11 +520,12 @@ ErrorCode ReadParallel::load_file(const char **file_names,
     if (MB_SUCCESS != tmp_result) {
       result = tmp_result;
       if (myPcomm->proc_config().proc_size() != 1) {
-        std::ostringstream ostr;
-        ostr << "Failed in step " << ParallelActionsNames[*vit] << std::endl;
-        std::string tmp_str;
-        if (MB_SUCCESS == mbImpl->get_last_error(tmp_str)) ostr << tmp_str << std::endl;
-        RR(ostr.str());
+        //std::ostringstream ostr;
+        //ostr << "Failed in step " << ParallelActionsNames[*vit] << std::endl;
+        //std::string tmp_str;
+        //if (MB_SUCCESS == mbImpl->get_last_error(tmp_str)) ostr << tmp_str << std::endl;
+        //RR(ostr.str());
+        SET_ERR_STR(result, "Failed in step " << ParallelActionsNames[*vit]);
       }
       break;
     }


https://bitbucket.org/fathomteam/moab/commits/e57113d57239/
Changeset:   e57113d57239
Branch:      danwu/error_handling_enhancement
User:        danwu
Date:        2014-07-14 17:30:24
Summary:     Applied new error handling code to ReadNC.cpp and NCHelper.cpp. Added two examples that read climate .nc files and trace back returned errors.

Affected #:  7 files

diff --git a/.gitignore b/.gitignore
index 52e35a8..ae08a0d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -36,6 +36,7 @@ examples/DeformMeshRemap
 examples/DirectAccessNoHoles
 examples/DirectAccessNoHolesF90
 examples/DirectAccessWithHoles
+examples/ErrorHandlingSimulation
 examples/examples.make
 examples/freem.mod
 examples/GetEntities
@@ -55,6 +56,8 @@ examples/ReduceExchangeTags
 examples/SetsNTags
 examples/structuredmesh
 examples/StructuredMeshSimple
+examples/TestErrorHandling
+examples/TestErrorHandlingPar
 examples/TestExodusII
 history??.jou
 hpctoolkit-*

diff --git a/examples/TestErrorHandling.cpp b/examples/TestErrorHandling.cpp
new file mode 100644
index 0000000..34d618c
--- /dev/null
+++ b/examples/TestErrorHandling.cpp
@@ -0,0 +1,93 @@
+/** @example TestErrorHandling.cpp \n
+ * Description: This example tests MOAB's trace back error handler in serial. \n
+ *
+ * <b>To run</b>: ./TestErrorHandling <test_case_num(1 to 3)> \n
+ */
+
+#include "moab/Core.hpp"
+#ifdef USE_MPI
+#include "moab_mpi.h"
+#endif
+
+#include <iostream>
+
+using namespace moab;
+using namespace std;
+
+// In this test case, an error MB_NOT_IMPLEMENTED is returned by MOAB
+ErrorCode TestErrorHandling_1()
+{
+  Core moab;
+  Interface& mb = moab;
+
+  // Load a CAM-FV file and read a variable on edges (not supported yet)
+  string test_file = string(MESH_DIR) + string("/io/fv3x46x72.t.3.nc");
+  ErrorCode rval = mb.load_file(test_file.c_str(), NULL, "VARIABLE=US");CHK_ERR(rval);
+
+  return MB_SUCCESS;
+}
+
+// In this test case, an error MB_TYPE_OUT_OF_RANGE is returned by MOAB
+ErrorCode TestErrorHandling_2()
+{
+  Core moab;
+  Interface& mb = moab;
+
+  // Load a HOMME file with an invalid GATHER_SET option
+  string test_file = string(MESH_DIR) + string("/io/homme3x3458.t.3.nc");
+  ErrorCode rval = mb.load_file(test_file.c_str(), NULL, "VARIABLE=T;GATHER_SET=0.1");CHK_ERR(rval);
+
+  return MB_SUCCESS;
+}
+
+// In this test case, an error MB_FAILURE is returned by MOAB
+ErrorCode TestErrorHandling_3()
+{
+  Core moab;
+  Interface& mb = moab;
+
+  // Load a CAM-FV file with  and a NULL file set
+  string test_file = string(MESH_DIR) + string("/io/fv3x46x72.t.3.nc");
+  ErrorCode rval = mb.load_file(test_file.c_str(), NULL, "NOMESH;VARIABLE=");CHK_ERR(rval);
+
+  return MB_SUCCESS;
+}
+
+int main(int argc, char** argv)
+{
+  if (argc < 2) {
+    cout << "Usage: " << argv[0] << " <test_case_num(1 to 3)>" << endl;
+    return 0;
+  }
+
+#ifdef USE_MPI
+  MPI_Init(&argc, &argv);
+#endif
+
+  MBErrorHandler_Init();
+
+  ErrorCode rval = MB_SUCCESS;
+
+  int test_case_num = atoi(argv[1]);
+  switch (test_case_num) {
+    case 1:
+      rval = TestErrorHandling_1();CHK_ERR(rval);
+      break;
+    case 2:
+      rval = TestErrorHandling_2();CHK_ERR(rval);
+      break;
+    case 3:
+      rval = TestErrorHandling_3();CHK_ERR(rval);
+      break;
+    default:
+      break;
+  }
+
+  MBErrorHandler_Finalize();
+
+#ifdef USE_MPI
+  MPI_Finalize();
+#endif
+
+  return 0;
+}

diff --git a/examples/TestErrorHandlingPar.cpp b/examples/TestErrorHandlingPar.cpp
new file mode 100644
index 0000000..2fd3171
--- /dev/null
+++ b/examples/TestErrorHandlingPar.cpp
@@ -0,0 +1,93 @@
+/** @example TestErrorHandlingPar.cpp \n
+ * Description: This example tests MOAB's trace back error handler in parallel.\n
+ *
+ * <b>To run</b>: mpiexec -np <n> ./TestErrorHandlingPar <test_case_num(1 to 2)> \n
+ */
+
+#include "moab/Core.hpp"
+#ifdef USE_MPI
+#include "moab_mpi.h"
+#endif
+
+#include <iostream>
+
+using namespace moab;
+using namespace std;
+
+// In this test case, a global fatal error MB_NOT_IMPLEMENTED is returned by MOAB
+// Note, it is printed by root processor 0 only
+ErrorCode TestErrorHandlingPar_1()
+{
+  Core moab;
+  Interface& mb = moab;
+
+  std::string opts = ";;";
+#ifdef USE_MPI
+  // Use parallel options
+  opts += "PARALLEL=READ_PART;PARTITION_METHOD=SQIJ";
+#endif
+
+  // Load a CAM-FV file and read a variable on edges (not supported yet)
+  string test_file = string(MESH_DIR) + string("/io/fv3x46x72.t.3.nc");
+  opts += ";VARIABLE=US";
+  ErrorCode rval = mb.load_file(test_file.c_str(), NULL, opts.c_str());CHK_ERR(rval);
+
+  return MB_SUCCESS;
+}
+
+// In this test case, a per-processor relevant error MB_FAILURE is returned by MOAB
+// Note, it is printed by all processors
+ErrorCode TestErrorHandlingPar_2()
+{
+  Core moab;
+  Interface& mb = moab;
+
+  std::string opts = ";;";
+#ifdef USE_MPI
+  // Use parallel options
+  opts += "PARALLEL=READ_PART;PARTITION_METHOD=UNKNOWN";
+#endif
+
+  // Load a CAM-FV file with an unknown partition method specified
+  string test_file = string(MESH_DIR) + string("/io/fv3x46x72.t.3.nc");
+  opts += ";VARIABLE=T";
+  ErrorCode rval = mb.load_file(test_file.c_str(), NULL, opts.c_str());CHK_ERR(rval);
+
+  return MB_SUCCESS;
+}
+
+int main(int argc, char** argv)
+{
+  if (argc < 2) {
+    cout << "Usage: " << argv[0] << " <test_case_num(1 to 2>" << endl;
+    return 0;
+  }
+
+#ifdef USE_MPI
+  MPI_Init(&argc, &argv);
+#endif
+
+  MBErrorHandler_Init();
+
+  ErrorCode rval = MB_SUCCESS;
+
+  int test_case_num = atoi(argv[1]);
+  switch (test_case_num) {
+    case 1:
+      rval = TestErrorHandlingPar_1();CHK_ERR(rval);
+      break;
+    case 2:
+      rval = TestErrorHandlingPar_2();CHK_ERR(rval);
+      break;
+    default:
+      break;
+  }
+
+  MBErrorHandler_Finalize();
+
+#ifdef USE_MPI
+  MPI_Finalize();
+#endif
+
+  return 0;
+}

diff --git a/examples/makefile b/examples/makefile
index c4dd9e7..09a5406 100644
--- a/examples/makefile
+++ b/examples/makefile
@@ -11,7 +11,7 @@ EXAMPLES = HelloMOAB GetEntities SetsNTags LoadPartial structuredmesh Structured
 PAREXAMPLES = HelloParMOAB ReduceExchangeTags LloydRelaxation CrystalRouterExample
 EXOIIEXAMPLES = TestExodusII
 F90EXAMPLES = DirectAccessNoHolesF90 PushParMeshIntoMoabF90
-ERROREXAMPLES = ErrorHandlingSimulation
+ERROREXAMPLES = ErrorHandlingSimulation TestErrorHandling TestErrorHandlingPar
 
 default: ${EXAMPLES} ${PAREXAMPLES} ${EXOIIEXAMPLES} ${F90EXAMPLES} ${ERROREXAMPLES}
 
@@ -67,14 +67,20 @@ DeformMeshRemap: DeformMeshRemap.o ${MOAB_LIBDIR}/libMOAB.la
 	${MOAB_CXX} -o $@ $< ${MOAB_LIBS_LINK} -lmbcoupler ${MOAB_LIBS_LINK}
 
 VisTags: VisTags.o ${MOAB_LIBDIR}/libMOAB.la
-	${MOAB_CXX} -o $@ $< ${MOAB_LIBS_LINK} 
+	${MOAB_CXX} -o $@ $< ${MOAB_LIBS_LINK}
 
 ReadWriteTest: ReadWriteTest.o ${MOAB_LIBDIR}/libMOAB.la
-	${MOAB_CXX} -o $@ $< ${MOAB_LIBS_LINK} 
+	${MOAB_CXX} -o $@ $< ${MOAB_LIBS_LINK}
 
 ErrorHandlingSimulation: ErrorHandlingSimulation.o ${MOAB_LIBDIR}/libMOAB.la
 	${MOAB_CXX} -o $@ $< ${MOAB_LIBS_LINK}
 
+TestErrorHandling: TestErrorHandling.o ${MOAB_LIBDIR}/libMOAB.la
+	${MOAB_CXX} -o $@ $< ${MOAB_LIBS_LINK}
+
+TestErrorHandlingPar: TestErrorHandlingPar.o ${MOAB_LIBDIR}/libMOAB.la
+	${MOAB_CXX} -o $@ $< ${MOAB_LIBS_LINK}
+
 clean:
 	rm -rf *.o *.mod *.h5m ${EXAMPLES} ${PAREXAMPLES} ${EXOIIEXAMPLES} ${F90EXAMPLES} ${ERROREXAMPLES}
 

diff --git a/src/io/Makefile.am b/src/io/Makefile.am
index 2d2d60b..d0f8d48 100644
--- a/src/io/Makefile.am
+++ b/src/io/Makefile.am
@@ -10,6 +10,7 @@ noinst_LTLIBRARIES = libmoabio.la
 libmoabio_la_LIBADD = $(NETCDF_LIBS) $(PNETCDF_LIBS) $(CGNS_LIBS) $(HDF5_LIBS) 
 
 AM_CPPFLAGS += -DIS_BUILDING_MB \
+               -DLOCDIR=src/io/ \
                -I..  -I$(srcdir)/.. -I$(srcdir)/../parallel
 
 if NETCDF_FILE

diff --git a/src/io/NCHelper.cpp b/src/io/NCHelper.cpp
index 613ce13..27dd3f7 100644
--- a/src/io/NCHelper.cpp
+++ b/src/io/NCHelper.cpp
@@ -7,15 +7,8 @@
 
 #include <sstream>
 
-#include "moab/ReadUtilIface.hpp"
 #include "MBTagConventions.hpp"
 
-#define ERRORR(rval, str) \
-  if (MB_SUCCESS != rval) {_readNC->readMeshIface->report_error("%s", str); return rval;}
-
-#define ERRORS(err, str) \
-  if (err) {_readNC->readMeshIface->report_error("%s", str); return MB_FAILURE;}
-
 namespace moab {
 
 NCHelper* NCHelper::get_nc_helper(ReadNC* readNC, int fileId, const FileOptions& opts, EntityHandle fileSet)
@@ -54,7 +47,7 @@ NCHelper* NCHelper::get_nc_helper(ReadNC* readNC, int fileId, const FileOptions&
       return new (std::nothrow) NCHelperHOMME(readNC, fileId, opts, fileSet);
     // gcrm reader
     else if (NCHelperGCRM::can_read_file(readNC))
-          return new (std::nothrow) NCHelperGCRM(readNC, fileId, opts, fileSet);
+      return new (std::nothrow) NCHelperGCRM(readNC, fileId, opts, fileSet);
   }
 
   // Unknown NetCDF grid (will fill this in later for POP, CICE and CLM)
@@ -80,22 +73,20 @@ ErrorCode NCHelper::create_conventional_tags(const std::vector<int>& tstep_nums)
   tag_name = "__NUM_DIMS";
   int numDims = dimNames.size();
   rval = mbImpl->tag_get_handle(tag_name.c_str(), 1, MB_TYPE_INTEGER, numDimsTag, MB_TAG_SPARSE | MB_TAG_CREAT);
-  ERRORR(rval, "Trouble creating __NUM_DIMS tag.");
+  CHK_ERR1_STR(rval, "Trouble creating conventional tag " << tag_name);
   rval = mbImpl->tag_set_data(numDimsTag, &_fileSet, 1, &numDims);
-  ERRORR(rval, "Trouble setting data for __NUM_DIMS tag.");
-  if (MB_SUCCESS == rval)
-    dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str());
+  CHK_ERR1_STR(rval, "Trouble setting data to conventional tag " << tag_name);
+  dbgOut.tprintf(2, "Conventional tag %s created\n", tag_name.c_str());
 
   // <__NUM_VARS>
   Tag numVarsTag = 0;
   tag_name = "__NUM_VARS";
   int numVars = varInfo.size();
   rval = mbImpl->tag_get_handle(tag_name.c_str(), 1, MB_TYPE_INTEGER, numVarsTag, MB_TAG_SPARSE | MB_TAG_CREAT);
-  ERRORR(rval, "Trouble creating __NUM_VARS tag.");
+  CHK_ERR1_STR(rval, "Trouble creating conventional tag " << tag_name);
   rval = mbImpl->tag_set_data(numVarsTag, &_fileSet, 1, &numVars);
-  ERRORR(rval, "Trouble setting data for __NUM_VARS tag.");
-  if (MB_SUCCESS == rval)
-    dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str());
+  CHK_ERR1_STR(rval, "Trouble setting data to conventional tag " << tag_name);
+  dbgOut.tprintf(2, "Conventional tag %s created\n", tag_name.c_str());
 
   // <__DIM_NAMES>
   Tag dimNamesTag = 0;
@@ -108,24 +99,22 @@ ErrorCode NCHelper::create_conventional_tags(const std::vector<int>& tstep_nums)
   }
   int dimnamesSz = dimnames.size();
   rval = mbImpl->tag_get_handle(tag_name.c_str(), 0, MB_TYPE_OPAQUE, dimNamesTag, MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN);
-  ERRORR(rval, "Trouble creating __DIM_NAMES tag.");
+  CHK_ERR1_STR(rval, "Trouble creating conventional tag " << tag_name);
   const void* ptr = dimnames.c_str();
   rval = mbImpl->tag_set_by_ptr(dimNamesTag, &_fileSet, 1, &ptr, &dimnamesSz);
-  ERRORR(rval, "Trouble setting data for __DIM_NAMES tag.");
-  if (MB_SUCCESS == rval)
-    dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str());
+  CHK_ERR1_STR(rval, "Trouble setting data to conventional tag " << tag_name);
+  dbgOut.tprintf(2, "Conventional tag %s created\n", tag_name.c_str());
 
   // <__DIM_LENS>
   Tag dimLensTag = 0;
   tag_name = "__DIM_LENS";
   int dimLensSz = dimLens.size();
   rval = mbImpl->tag_get_handle(tag_name.c_str(), 0, MB_TYPE_INTEGER, dimLensTag, MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN);
-  ERRORR(rval, "Trouble creating __DIM_LENS tag.");
+  CHK_ERR1_STR(rval, "Trouble creating conventional tag " << tag_name);
   ptr = &(dimLens[0]);
   rval = mbImpl->tag_set_by_ptr(dimLensTag, &_fileSet, 1, &ptr, &dimLensSz);
-  ERRORR(rval, "Trouble setting data for __DIM_LENS tag.");
-  if (MB_SUCCESS == rval)
-    dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str());
+  CHK_ERR1_STR(rval, "Trouble setting data to conventional tag " << tag_name);
+  dbgOut.tprintf(2, "Conventional tag %s created\n", tag_name.c_str());
 
   // <__VAR_NAMES>
   Tag varNamesTag = 0;
@@ -138,12 +127,11 @@ ErrorCode NCHelper::create_conventional_tags(const std::vector<int>& tstep_nums)
   }
   int varnamesSz = varnames.size();
   rval = mbImpl->tag_get_handle(tag_name.c_str(), 0, MB_TYPE_OPAQUE, varNamesTag, MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN);
-  ERRORR(rval, "Trouble creating __VAR_NAMES tag.");
+  CHK_ERR1_STR(rval, "Trouble creating conventional tag " << tag_name);
   ptr = varnames.c_str();
   rval = mbImpl->tag_set_by_ptr(varNamesTag, &_fileSet, 1, &ptr, &varnamesSz);
-  ERRORR(rval, "Trouble setting data for __VAR_NAMES tag.");
-  if (MB_SUCCESS == rval)
-    dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str());
+  CHK_ERR1_STR(rval, "Trouble setting data to conventional tag " << tag_name);
+  dbgOut.tprintf(2, "Conventional tag %s created\n", tag_name.c_str());
 
   // __<dim_name>_LOC_MINMAX (for time)
   for (unsigned int i = 0; i != dimNamesSz; i++) {
@@ -156,11 +144,10 @@ ErrorCode NCHelper::create_conventional_tags(const std::vector<int>& tstep_nums)
       val[0] = 0;
       val[1] = nTimeSteps - 1;
       rval = mbImpl->tag_get_handle(tag_name.c_str(), 2, MB_TYPE_INTEGER, tagh, MB_TAG_SPARSE | MB_TAG_CREAT);
-      ERRORR(rval, "Trouble creating __<dim_name>_LOC_MINMAX tag.");
+      CHK_ERR1_STR(rval, "Trouble creating conventional tag " << tag_name);
       rval = mbImpl->tag_set_data(tagh, &_fileSet, 1, &val[0]);
-      ERRORR(rval, "Trouble setting data for __<dim_name>_LOC_MINMAX tag.");
-      if (MB_SUCCESS == rval)
-        dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str());
+      CHK_ERR1_STR(rval, "Trouble setting data to conventional tag " << tag_name);
+      dbgOut.tprintf(2, "Conventional tag %s created\n", tag_name.c_str());
     }
   }
 
@@ -180,11 +167,10 @@ ErrorCode NCHelper::create_conventional_tags(const std::vector<int>& tstep_nums)
       ss_tag_name << "__" << dimNames[i] << "_LOC_VALS";
       tag_name = ss_tag_name.str();
       rval = mbImpl->tag_get_handle(tag_name.c_str(), val.size(), MB_TYPE_INTEGER, tagh, MB_TAG_SPARSE | MB_TAG_CREAT);
-      ERRORR(rval, "Trouble creating __<dim_name>_LOC_VALS tag.");
+      CHK_ERR1_STR(rval, "Trouble creating conventional tag " << tag_name);
       rval = mbImpl->tag_set_data(tagh, &_fileSet, 1, &val[0]);
-      ERRORR(rval, "Trouble setting data for __<dim_name>_LOC_VALS tag.");
-      if (MB_SUCCESS == rval)
-        dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str());
+      CHK_ERR1_STR(rval, "Trouble setting data to conventional tag " << tag_name);
+      dbgOut.tprintf(2, "Conventional tag %s created\n", tag_name.c_str());
     }
   }
 
@@ -201,41 +187,39 @@ ErrorCode NCHelper::create_conventional_tags(const std::vector<int>& tstep_nums)
     for (unsigned int i = 0; i != varDimSz; i++) {
       Tag tmptag = 0;
       std::string tmptagname = dimNames[varInfo[mapIter->first].varDims[i]];
-      mbImpl->tag_get_handle(tmptagname.c_str(), 0, MB_TYPE_OPAQUE, tmptag, MB_TAG_ANY);
+      rval = mbImpl->tag_get_handle(tmptagname.c_str(), 0, MB_TYPE_OPAQUE, tmptag, MB_TAG_ANY);
+      CHK_ERR1_STR(rval, "Trouble getting tag " << tmptagname);
       varDimTags[i] = tmptag;
     }
     rval = mbImpl->tag_get_handle(tag_name.c_str(), varDimSz, MB_TYPE_HANDLE, varNamesDimsTag, MB_TAG_SPARSE | MB_TAG_CREAT);
-    ERRORR(rval, "Trouble creating __<var_name>_DIMS tag.");
+    CHK_ERR1_STR(rval, "Trouble creating conventional tag " << tag_name);
     rval = mbImpl->tag_set_data(varNamesDimsTag, &_fileSet, 1, &(varDimTags[0]));
-    ERRORR(rval, "Trouble setting data for __<var_name>_DIMS tag.");
-    if (MB_SUCCESS == rval)
-      dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str());
+    CHK_ERR1_STR(rval, "Trouble setting data to conventional tag " << tag_name);
+    dbgOut.tprintf(2, "Conventional tag %s created\n", tag_name.c_str());
   }
 
   // <PARTITION_METHOD>
   Tag part_tag = scdi->part_method_tag();
   if (!part_tag)
-    ERRORR(MB_FAILURE, "Trouble getting PARTITION_METHOD tag.");
+    SET_ERR(MB_FAILURE, "Trouble getting PARTITION_METHOD tag");
   rval = mbImpl->tag_set_data(part_tag, &_fileSet, 1, &partMethod);
-  ERRORR(rval, "Trouble setting data for PARTITION_METHOD tag.");
-  if (MB_SUCCESS == rval)
-    dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str());
+  CHK_ERR1(rval, "Trouble setting data to PARTITION_METHOD tag");
+  dbgOut.tprintf(2, "Conventional tag %s created\n", tag_name.c_str());
 
   // <__GLOBAL_ATTRIBS>
   tag_name = "__GLOBAL_ATTRIBS";
   Tag globalAttTag = 0;
   rval = mbImpl->tag_get_handle(tag_name.c_str(), 0, MB_TYPE_OPAQUE, globalAttTag, MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN);
-  ERRORR(rval, "Trouble creating __GLOBAL_ATTRIBS tag.");
+  CHK_ERR1_STR(rval, "Trouble creating conventional tag " << tag_name);
   std::string gattVal;
   std::vector<int> gattLen;
   rval = create_attrib_string(globalAtts, gattVal, gattLen);
-  ERRORR(rval, "Trouble creating global attribute string.");
+  CHK_ERR1(rval, "Trouble creating global attribute string");
   const void* gattptr = gattVal.c_str();
   int globalAttSz = gattVal.size();
   rval = mbImpl->tag_set_by_ptr(globalAttTag, &_fileSet, 1, &gattptr, &globalAttSz);
-  ERRORR(rval, "Trouble setting data for __GLOBAL_ATTRIBS tag.");
-  if (MB_SUCCESS == rval)
-    dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str());
+  CHK_ERR1_STR(rval, "Trouble setting data to conventional tag " << tag_name);
+  dbgOut.tprintf(2, "Conventional tag %s created\n", tag_name.c_str());
 
   // <__GLOBAL_ATTRIBS_LEN>
   tag_name = "__GLOBAL_ATTRIBS_LEN";
@@ -243,11 +227,10 @@ ErrorCode NCHelper::create_conventional_tags(const std::vector<int>& tstep_nums)
   if (gattLen.size() == 0)
     gattLen.push_back(0);
   rval = mbImpl->tag_get_handle(tag_name.c_str(), gattLen.size(), MB_TYPE_INTEGER, globalAttLenTag, MB_TAG_SPARSE | MB_TAG_CREAT);
-  ERRORR(rval, "Trouble creating __GLOBAL_ATTRIBS_LEN tag.");
+  CHK_ERR1_STR(rval, "Trouble creating conventional tag " << tag_name);
   rval = mbImpl->tag_set_data(globalAttLenTag, &_fileSet, 1, &gattLen[0]);
-  ERRORR(rval, "Trouble setting data for __GLOBAL_ATTRIBS_LEN tag.");
-  if (MB_SUCCESS == rval)
-    dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str());
+  CHK_ERR1_STR(rval, "Trouble setting data to conventional tag " << tag_name);
+  dbgOut.tprintf(2, "Conventional tag %s created\n", tag_name.c_str());
 
   // __<var_name>_ATTRIBS and __<var_name>_ATTRIBS_LEN
   for (mapIter = varInfo.begin(); mapIter != varInfo.end(); ++mapIter) {
@@ -256,7 +239,7 @@ ErrorCode NCHelper::create_conventional_tags(const std::vector<int>& tstep_nums)
     tag_name = ssTagName.str();
     Tag varAttTag = 0;
     rval = mbImpl->tag_get_handle(tag_name.c_str(), 0, MB_TYPE_OPAQUE, varAttTag, MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN);
-    ERRORR(rval, "Trouble creating __<var_name>_ATTRIBS tag.");
+    CHK_ERR1_STR(rval, "Trouble creating conventional tag " << tag_name);
 
     std::string varAttVal;
     std::vector<int> varAttLen;
@@ -272,16 +255,15 @@ ErrorCode NCHelper::create_conventional_tags(const std::vector<int>& tstep_nums)
     }
     else {
       rval = create_attrib_string(mapIter->second.varAtts, varAttVal, varAttLen);
-      ERRORR(rval, "Trouble creating attribute string.");
+      CHK_ERR1_STR(rval, "Trouble creating attribute string for variable " << mapIter->first);
     }
     const void* varAttPtr = varAttVal.c_str();
     int varAttSz = varAttVal.size();
     if (0 == varAttSz)
       varAttSz = 1;
     rval = mbImpl->tag_set_by_ptr(varAttTag, &_fileSet, 1, &varAttPtr, &varAttSz);
-    ERRORR(rval, "Trouble setting data for __<var_name>_ATTRIBS tag.");
-    if (MB_SUCCESS == rval)
-      dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str());
+    CHK_ERR1_STR(rval, "Trouble setting data to conventional tag " << tag_name);
+    dbgOut.tprintf(2, "Conventional tag %s created\n", tag_name.c_str());
 
     ssTagName << "_LEN";
     tag_name = ssTagName.str();
@@ -289,11 +271,10 @@ ErrorCode NCHelper::create_conventional_tags(const std::vector<int>& tstep_nums)
     if (0 == varAttLen.size())
       varAttLen.push_back(0);
     rval = mbImpl->tag_get_handle(tag_name.c_str(), varAttLen.size(), MB_TYPE_INTEGER, varAttLenTag, MB_TAG_SPARSE | MB_TAG_CREAT);
-    ERRORR(rval, "Trouble creating __<var_name>_ATTRIBS_LEN tag.");
+    CHK_ERR1_STR(rval, "Trouble creating conventional tag " << tag_name);
     rval = mbImpl->tag_set_data(varAttLenTag, &_fileSet, 1, &varAttLen[0]);
-    ERRORR(rval, "Trouble setting data for __<var_name>_ATTRIBS_LEN tag.");
-    if (MB_SUCCESS == rval)
-      dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str());
+    CHK_ERR1_STR(rval, "Trouble setting data to conventional tag " << tag_name);
+    dbgOut.tprintf(2, "Conventional tag %s created\n", tag_name.c_str());
   }
 
   // <__VAR_NAMES_LOCATIONS>
@@ -302,14 +283,13 @@ ErrorCode NCHelper::create_conventional_tags(const std::vector<int>& tstep_nums)
   std::vector<int> varNamesLocs(varInfo.size());
   rval = mbImpl->tag_get_handle(tag_name.c_str(), varNamesLocs.size(), MB_TYPE_INTEGER, varNamesLocsTag, MB_TAG_CREAT
       | MB_TAG_SPARSE);
-  ERRORR(rval, "Trouble creating __VAR_NAMES_LOCATIONS tag.");
+  CHK_ERR1_STR(rval, "Trouble creating conventional tag " << tag_name);
   for (mapIter = varInfo.begin(); mapIter != varInfo.end(); ++mapIter) {
     varNamesLocs[std::distance(varInfo.begin(), mapIter)] = mapIter->second.entLoc;
   }
   rval = mbImpl->tag_set_data(varNamesLocsTag, &_fileSet, 1, &varNamesLocs[0]);
-  ERRORR(rval, "Trouble setting data for __VAR_NAMES_LOCATIONS tag.");
-  if (MB_SUCCESS == rval)
-    dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str());
+  CHK_ERR1_STR(rval, "Trouble setting data to conventional tag " << tag_name);
+  dbgOut.tprintf(2, "Conventional tag %s created\n", tag_name.c_str());
 
   // <__MESH_TYPE>
   Tag meshTypeTag = 0;
@@ -317,13 +297,12 @@ ErrorCode NCHelper::create_conventional_tags(const std::vector<int>& tstep_nums)
   std::string meshTypeName = get_mesh_type_name();
 
   rval = mbImpl->tag_get_handle(tag_name.c_str(), 0, MB_TYPE_OPAQUE, meshTypeTag, MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN);
-  ERRORR(rval, "Trouble creating __MESH_TYPE tag.");
+  CHK_ERR1_STR(rval, "Trouble creating conventional tag " << tag_name);
   ptr = meshTypeName.c_str();
   int leng = meshTypeName.size();
   rval = mbImpl->tag_set_by_ptr(meshTypeTag, &_fileSet, 1, &ptr, &leng);
-  ERRORR(rval, "Trouble setting data for __MESH_TYPE tag.");
-  if (MB_SUCCESS == rval)
-    dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str());
+  CHK_ERR1_STR(rval, "Trouble setting data to conventional tag " << tag_name);
+  dbgOut.tprintf(2, "Conventional tag %s created\n", tag_name.c_str());
 
   return MB_SUCCESS;
 }
@@ -344,9 +323,9 @@ ErrorCode NCHelper::update_time_tag_vals()
   const void* data = NULL;
   int time_tag_size = 0;
   rval = mbImpl->tag_get_handle(time_tag_name.c_str(), 0, MB_TYPE_DOUBLE, time_tag, MB_TAG_VARLEN);
-  ERRORR(rval, "Trouble getting time tag.");
+  CHK_ERR1_STR(rval, "Trouble getting tag " << time_tag_name);
   rval = mbImpl->tag_get_by_ptr(time_tag, &_fileSet, 1, &data, &time_tag_size);
-  ERRORR(rval, "Trouble getting values for time tag.");
+  CHK_ERR1_STR(rval, "Trouble getting data of tag " << time_tag_name);
   const double* time_tag_vals = static_cast<const double*>(data);
 
   // Merge tVals (read from current file) to existing time tag
@@ -375,7 +354,7 @@ ErrorCode NCHelper::update_time_tag_vals()
   data = &merged_time_vals[0];
   time_tag_size = merged_time_vals.size();
   rval = mbImpl->tag_set_by_ptr(time_tag, &_fileSet, 1, &data, &time_tag_size);
-  ERRORR(rval, "Failed to set data for time tag.");
+  CHK_ERR1_STR(rval, "Trouble setting data to tag " << time_tag_name);
 
   return MB_SUCCESS;
 }
@@ -424,7 +403,7 @@ ErrorCode NCHelper::read_variables_setup(std::vector<std::string>& var_names, st
           vdatas.push_back(vd);
       }
       else {
-        ERRORR(MB_FAILURE, "Couldn't find specified variable.");
+        SET_ERR_STR(MB_FAILURE, "Couldn't find specified variable " << var_names[i]);
       }
     }
   }
@@ -470,7 +449,7 @@ ErrorCode NCHelper::read_variables_to_set(std::vector<ReadNC::VarData>& vdatas,
   DebugOutput& dbgOut = _readNC->dbgOut;
 
   ErrorCode rval = read_variables_to_set_allocate(vdatas, tstep_nums);
-  ERRORR(rval, "Trouble allocating space to read set variables.");
+  CHK_ERR1(rval, "Trouble allocating space to read set variables");
 
   // Finally, read into that space
   int success;
@@ -490,27 +469,30 @@ ErrorCode NCHelper::read_variables_to_set(std::vector<ReadNC::VarData>& vdatas,
         case NC_CHAR:
           success = NCFUNCAG(_vara_text)(_fileId, vdatas[i].varId, &vdatas[i].readStarts[0],
                                         &vdatas[i].readCounts[0], (char*) data);
-          ERRORS(success, "Failed to read char data.");
+          if (success)
+            SET_ERR_STR(MB_FAILURE, "Failed to read byte/char data for variable " << vdatas[i].varName);
           break;
         case NC_SHORT:
         case NC_INT:
           success = NCFUNCAG(_vara_int)(_fileId, vdatas[i].varId, &vdatas[i].readStarts[0],
                                         &vdatas[i].readCounts[0], (int*) data);
-          ERRORS(success, "Failed to read int data.");
+          if (success)
+            SET_ERR_STR(MB_FAILURE, "Failed to read short/int data for variable " << vdatas[i].varName);
           break;
         case NC_FLOAT:
         case NC_DOUBLE:
           success = NCFUNCAG(_vara_double)(_fileId, vdatas[i].varId, &vdatas[i].readStarts[0],
                                         &vdatas[i].readCounts[0], (double*) data);
-          ERRORS(success, "Failed to read double data.");
+          if (success)
+            SET_ERR_STR(MB_FAILURE, "Failed to read float/double data for variable " << vdatas[i].varName);
           break;
         default:
-          ERRORR(MB_FAILURE, "Unexpected variable data type.");
+          SET_ERR_STR(MB_FAILURE, "Unexpected data type for variable " << vdatas[i].varName);
       }
 
       dbgOut.tprintf(2, "Setting data for variable %s, time step %d\n", vdatas[i].varName.c_str(), tstep_nums[t]);
       rval = mbImpl->tag_set_by_ptr(vdatas[i].varTags[t], &_fileSet, 1, &data, &vdatas[i].sz);
-      ERRORR(rval, "Failed to set data for variable.");
+      CHK_ERR1_STR(rval, "Trouble setting tag data for variable " << vdatas[i].varName);
 
       // Memory pointed by pointer data can be deleted, as tag_set_by_ptr() has already copied the tag values
       switch (vdatas[i].varDataType) {
@@ -553,7 +535,7 @@ ErrorCode NCHelper::read_coordinate(const char* var_name, int lmin, int lmax, st
   std::map<std::string, ReadNC::VarData>& varInfo = _readNC->varInfo;
   std::map<std::string, ReadNC::VarData>::iterator vmit = varInfo.find(var_name);
   if (varInfo.end() == vmit)
-    return MB_FAILURE;
+    SET_ERR_STR(MB_FAILURE, "Couldn't find variable " << var_name);
 
   assert(lmin >= 0 && lmax >= lmin);
   NCDF_SIZE tstart = lmin;
@@ -571,10 +553,11 @@ ErrorCode NCHelper::read_coordinate(const char* var_name, int lmin, int lmax, st
     case NC_DOUBLE:
       // Read float as double
       success = NCFUNCAG(_vars_double)(_fileId, (*vmit).second.varId, &tstart, &tcount, &dum_stride, &cvals[0]);
-      ERRORS(success, "Failed to get coordinate values.");
+      if (success)
+        SET_ERR_STR(MB_FAILURE, "Failed to read float/double data for variable " << var_name);
       break;
     default:
-      ERRORR(MB_FAILURE, "Unexpected variable data type.");
+      SET_ERR_STR(MB_FAILURE, "Unexpected data type for variable " << var_name);
   }
 
   return MB_SUCCESS;
@@ -611,11 +594,11 @@ ErrorCode NCHelper::get_tag_to_set(ReadNC::VarData& var_data, int tstep_num, Tag
       rval = mbImpl->tag_get_handle(tag_name.str().c_str(), 0, MB_TYPE_DOUBLE, tagh, MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN);
       break;
     default:
-      ERRORR(MB_FAILURE, "Unexpected variable data type.");
+      SET_ERR_STR(MB_FAILURE, "Unexpected data type for variable " << var_data.varName);
   }
 
-  if (MB_SUCCESS == rval)
-    dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.str().c_str());
+  CHK_ERR1_STR(rval, "Trouble creating tag " << tag_name.str());
+  dbgOut.tprintf(2, "Tag %s created\n", tag_name.str().c_str());
 
   return rval;
 }
@@ -648,11 +631,11 @@ ErrorCode NCHelper::get_tag_to_nonset(ReadNC::VarData& var_data, int tstep_num,
       rval = mbImpl->tag_get_handle(tag_name.str().c_str(), num_lev, MB_TYPE_DOUBLE, tagh, MB_TAG_DENSE | MB_TAG_CREAT);
       break;
     default:
-      ERRORR(MB_FAILURE, "Unexpected variable data type.");
+      SET_ERR_STR(MB_FAILURE, "Unexpected data type for variable " << var_data.varName);
   }
 
-  if (MB_SUCCESS == rval)
-    dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.str().c_str());
+  CHK_ERR1_STR(rval, "Trouble creating tag " << tag_name.str());
+  dbgOut.tprintf(2, "Tag %s created\n", tag_name.str().c_str());
 
   return rval;
 }
@@ -673,39 +656,44 @@ ErrorCode NCHelper::create_attrib_string(const std::map<std::string, ReadNC::Att
         sz = attIt->second.attLen;
         attData = (char *) malloc(sz);
         success = NCFUNC(get_att_text)(_fileId, attIt->second.attVarId, attIt->second.attName.c_str(), (char*) attData);
-        ERRORS(success, "Failed to read attribute char data.");
+        if (success)
+          SET_ERR_STR(MB_FAILURE, "Failed to read byte/char data for attribute " << attIt->second.attName);
         ssAtt << "char;";
         break;
       case NC_SHORT:
         sz = attIt->second.attLen * sizeof(short);
         attData = (short *) malloc(sz);
         success = NCFUNC(get_att_short)(_fileId, attIt->second.attVarId, attIt->second.attName.c_str(), (short*) attData);
-        ERRORS(success, "Failed to read attribute short data.");
+        if (success)
+          SET_ERR_STR(MB_FAILURE, "Failed to read short data for attribute " << attIt->second.attName);
         ssAtt << "short;";
         break;
       case NC_INT:
         sz = attIt->second.attLen * sizeof(int);
         attData = (int *) malloc(sz);
         success = NCFUNC(get_att_int)(_fileId, attIt->second.attVarId, attIt->second.attName.c_str(), (int*) attData);
-        ERRORS(success, "Failed to read attribute int data.");
+        if (success)
+          SET_ERR_STR(MB_FAILURE, "Failed to read int data for attribute " << attIt->second.attName);
         ssAtt << "int;";
         break;
       case NC_FLOAT:
         sz = attIt->second.attLen * sizeof(float);
         attData = (float *) malloc(sz);
         success = NCFUNC(get_att_float)(_fileId, attIt->second.attVarId, attIt->second.attName.c_str(), (float*) attData);
-        ERRORS(success, "Failed to read attribute float data.");
+        if (success)
+          SET_ERR_STR(MB_FAILURE, "Failed to read float data for attribute " << attIt->second.attName);
         ssAtt << "float;";
         break;
       case NC_DOUBLE:
         sz = attIt->second.attLen * sizeof(double);
         attData = (double *) malloc(sz);
         success = NCFUNC(get_att_double)(_fileId, attIt->second.attVarId, attIt->second.attName.c_str(), (double*) attData);
-        ERRORS(success, "Failed to read attribute double data.");
+        if (success)
+          SET_ERR_STR(MB_FAILURE, "Failed to read double data for attribute " << attIt->second.attName);
         ssAtt << "double;";
         break;
       default:
-        ERRORR(MB_FAILURE, "Unexpected attribute data type.");
+        SET_ERR_STR(MB_FAILURE, "Unexpected data type for attribute " << attIt->second.attName);
     }
     char* tmpc = (char *) attData;
     for (unsigned int counter = 0; counter != sz; ++counter)
@@ -739,7 +727,7 @@ ErrorCode NCHelper::create_dummy_variables()
     int sizeTotalVar = varInfo.size();
     std::string var_name(dimNames[i]);
     ReadNC::VarData& data = varInfo[var_name];
-    data.varName = std::string(var_name);
+    data.varName = var_name;
     data.varId = sizeTotalVar;
     data.varTags.resize(1, 0);
     data.varDataType = NC_INT;
@@ -747,23 +735,23 @@ ErrorCode NCHelper::create_dummy_variables()
     data.varDims[0] = (int)i;
     data.numAtts = 0;
     data.entLoc = ReadNC::ENTLOCSET;
-    dummyVarNames.insert(dimNames[i]);
-    dbgOut.tprintf(2, "Dummy coordinate variable created for dimension %s\n", dimNames[i].c_str());
+    dummyVarNames.insert(var_name);
+    dbgOut.tprintf(2, "Dummy coordinate variable created for dimension %s\n", var_name.c_str());
 
     // Create a corresponding sparse tag
     Tag tagh;
-    ErrorCode rval = mbImpl->tag_get_handle(dimNames[i].c_str(), 0, MB_TYPE_INTEGER, tagh,
+    ErrorCode rval = mbImpl->tag_get_handle(var_name.c_str(), 0, MB_TYPE_INTEGER, tagh,
                                             MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN);
-    ERRORR(rval, "Failed to create tag for a dummy coordinate variable.");
+    CHK_ERR1_STR(rval, "Trouble creating tag for dummy coordinate variable " << var_name);
 
     // Tag value is the dimension length
     const void* ptr = &dimLens[i];
     // Tag size is 1
     int size = 1;
     rval = mbImpl->tag_set_by_ptr(tagh, &_fileSet, 1, &ptr, &size);
-    ERRORR(rval, "Failed to set data for dimension tag.");
+    CHK_ERR1_STR(rval, "Trouble setting tag data for dummy coordinate variable " << var_name);
 
-    dbgOut.tprintf(2, "Sparse tag created for dimension %s\n", dimNames[i].c_str());
+    dbgOut.tprintf(2, "Sparse tag created for dimension %s\n", var_name.c_str());
   }
 
   return MB_SUCCESS;
@@ -784,7 +772,7 @@ ErrorCode NCHelper::read_variables_to_set_allocate(std::vector<ReadNC::VarData>&
       vdatas[i].readCounts.push_back(1);
 
       // Next: other dimensions
-      for (unsigned int idx = 1; idx != vdatas[i].varDims.size(); idx++){
+      for (unsigned int idx = 1; idx != vdatas[i].varDims.size(); idx++) {
         vdatas[i].readStarts.push_back(0);
         vdatas[i].readCounts.push_back(dimLens[vdatas[i].varDims[idx]]);
       }
@@ -796,7 +784,7 @@ ErrorCode NCHelper::read_variables_to_set_allocate(std::vector<ReadNC::VarData>&
         vdatas[i].readCounts.push_back(1);
       }
       else {
-        for (unsigned int idx = 0; idx != vdatas[i].varDims.size(); idx++){
+        for (unsigned int idx = 0; idx != vdatas[i].varDims.size(); idx++) {
           vdatas[i].readStarts.push_back(0);
           vdatas[i].readCounts.push_back(dimLens[vdatas[i].varDims[idx]]);
         }
@@ -813,13 +801,13 @@ ErrorCode NCHelper::read_variables_to_set_allocate(std::vector<ReadNC::VarData>&
       dbgOut.tprintf(2, "Reading variable %s, time step %d\n", vdatas[i].varName.c_str(), tstep_nums[t]);
 
       if (tstep_nums[t] >= dimLens[tDim]) {
-        ERRORR(MB_INDEX_OUT_OF_RANGE, "Wrong value for a timestep number.");
+        SET_ERR_STR(MB_INDEX_OUT_OF_RANGE, "Wrong value for timestep number " << tstep_nums[t]);
       }
 
       // Get the tag to read into
       if (!vdatas[i].varTags[t]) {
         rval = get_tag_to_set(vdatas[i], tstep_nums[t], vdatas[i].varTags[t]);
-        ERRORR(rval, "Trouble getting tag for a set variable.");
+        CHK_ERR1_STR(rval, "Trouble getting tag to set variable " << vdatas[i].varName);
       }
 
       switch (vdatas[i].varDataType) {
@@ -836,7 +824,7 @@ ErrorCode NCHelper::read_variables_to_set_allocate(std::vector<ReadNC::VarData>&
           vdatas[i].varDatas[t] = new double[vdatas[i].sz];
           break;
         default:
-          ERRORR(MB_FAILURE, "Unexpected variable data type.");
+          SET_ERR_STR(MB_FAILURE, "Unexpected data type for variable " << vdatas[i].varName);
       }
 
       // Loop continues only for set variables with timesteps, e.g. xtime(Time) or xtime(Time, StrLen)
@@ -854,7 +842,7 @@ ErrorCode ScdNCHelper::check_existing_mesh() {
   // Get the number of vertices
   int num_verts;
   ErrorCode rval = mbImpl->get_number_entities_by_dimension(_fileSet, 0, num_verts);
-  ERRORR(rval, "Trouble getting number of vertices.");
+  CHK_ERR1(rval, "Trouble getting number of vertices");
 
   /*
   // Check against parameters
@@ -862,7 +850,7 @@ ErrorCode ScdNCHelper::check_existing_mesh() {
   if (num_verts > 0) {
     int expected_verts = (lDims[3] - lDims[0] + 1) * (lDims[4] - lDims[1] + 1) * (-1 == lDims[2] ? 1 : lDims[5] - lDims[2] + 1);
     if (num_verts != expected_verts) {
-      ERRORR(MB_FAILURE, "Number of vertices doesn't match.");
+      SET_ERR(MB_FAILURE, "Number of vertices doesn't match");
     }
   }
   */
@@ -870,7 +858,7 @@ ErrorCode ScdNCHelper::check_existing_mesh() {
   // Check the number of elements too
   int num_elems;
   rval = mbImpl->get_number_entities_by_dimension(_fileSet, (-1 == lCDims[2] ? 2 : 3), num_elems);
-  ERRORR(rval, "Trouble getting number of elements.");
+  CHK_ERR1(rval, "Trouble getting number of elements");
 
   /*
   // Check against parameters
@@ -878,7 +866,7 @@ ErrorCode ScdNCHelper::check_existing_mesh() {
   if (num_elems > 0) {
     int expected_elems = (lCDims[3] - lCDims[0] + 1) * (lCDims[4] - lCDims[1] + 1) * (-1 == lCDims[2] ? 1 : (lCDims[5] - lCDims[2] + 1));
     if (num_elems != expected_elems) {
-      ERRORR(MB_FAILURE, "Number of elements doesn't match.");
+      SET_ERR(MB_FAILURE, "Number of elements doesn't match");
     }
   }
   */
@@ -900,7 +888,7 @@ ErrorCode ScdNCHelper::create_mesh(Range& faces)
 
   ErrorCode rval = scdi->construct_box(HomCoord(lDims[0], lDims[1], lDims[2], 1), HomCoord(lDims[3], lDims[4], lDims[5], 1), 
                                        NULL, 0, scd_box, locallyPeriodic, &parData, true);
-  ERRORR(rval, "Trouble creating scd vertex sequence.");
+  CHK_ERR1(rval, "Trouble creating scd vertex sequence");
 
   // Add verts to tmp_range first, so we can duplicate global ids in vertex ids
   tmp_range.insert(scd_box->start_vertex(), scd_box->start_vertex() + scd_box->num_vertices() - 1);
@@ -909,11 +897,11 @@ ErrorCode ScdNCHelper::create_mesh(Range& faces)
     int count;
     void* data;
     rval = mbImpl->tag_iterate(*mpFileIdTag, tmp_range.begin(), tmp_range.end(), count, data);
-    ERRORR(rval, "Failed to get tag iterator on file id tag.");
+    CHK_ERR1(rval, "Failed to iterate file ID tag on local vertices");
     assert(count == scd_box->num_vertices());
     int* fid_data = (int*) data;
     rval = mbImpl->tag_iterate(mGlobalIdTag, tmp_range.begin(), tmp_range.end(), count, data);
-    ERRORR(rval, "Failed to get tag iterator on global id tag.");
+    CHK_ERR1(rval, "Failed to iterate global ID tag on local vertices");
     assert(count == scd_box->num_vertices());
     int* gid_data = (int*) data;
     for (int i = 0; i < count; i++)
@@ -924,14 +912,14 @@ ErrorCode ScdNCHelper::create_mesh(Range& faces)
   tmp_range.insert(scd_box->start_element(), scd_box->start_element() + scd_box->num_elements() - 1);
   tmp_range.insert(scd_box->box_set());
   rval = mbImpl->add_entities(_fileSet, tmp_range);
-  ERRORR(rval, "Couldn't add new vertices to file set.");
+  CHK_ERR1(rval, "Couldn't add new vertices to current file set");
 
   dbgOut.tprintf(1, "scdbox %d quads, %d vertices\n", scd_box->num_elements(), scd_box->num_vertices());
 
   // Set the vertex coordinates
   double *xc, *yc, *zc;
   rval = scd_box->get_coordinate_arrays(xc, yc, zc);
-  ERRORR(rval, "Couldn't get vertex coordinate arrays.");
+  CHK_ERR1(rval, "Couldn't get vertex coordinate arrays");
 
   int i, j, k, il, jl, kl;
   int dil = lDims[3] - lDims[0] + 1;
@@ -958,7 +946,7 @@ ErrorCode ScdNCHelper::create_mesh(Range& faces)
   std::vector<int> gids(num_verts);
   Range verts(scd_box->start_vertex(), scd_box->start_vertex() + scd_box->num_vertices() - 1);
   rval = mbImpl->tag_get_data(mGlobalIdTag, verts, &gids[0]);
-  ERRORR(rval, "Trouble getting gid values.");
+  CHK_ERR1(rval, "Trouble getting local gid values of vertices");
   int vmin = *(std::min_element(gids.begin(), gids.end())), vmax = *(std::max_element(gids.begin(), gids.end()));
   dbgOut.tprintf(1, "Vertex gids %d-%d\n", vmin, vmax);
 #endif
@@ -970,14 +958,14 @@ ErrorCode ScdNCHelper::create_mesh(Range& faces)
     assert(scd_box->boundary_complete());
     EntityHandle dum_ent = scd_box->start_element();
     rval = mbImpl->list_entities(&dum_ent, 1);
-    ERRORR(rval, "Trouble listing first hex.");
+    CHK_ERR1(rval, "Trouble listing first hex");
 
     std::vector<EntityHandle> connect;
     rval = mbImpl->get_connectivity(&dum_ent, 1, connect);
-    ERRORR(rval, "Trouble getting connectivity.");
+    CHK_ERR1(rval, "Trouble getting connectivity");
 
     rval = mbImpl->list_entities(&connect[0], connect.size());
-    ERRORR(rval, "Trouble listing element connectivity.");
+    CHK_ERR1(rval, "Trouble listing element connectivity");
   }
 
   Range edges;
@@ -985,7 +973,7 @@ ErrorCode ScdNCHelper::create_mesh(Range& faces)
 
   // Create COORDS tag for quads
   rval = create_quad_coordinate_tag();
-  ERRORR(rval, "Trouble creating coordinate tags to entities quads");
+  CHK_ERR1(rval, "Trouble creating COORDS tag for quads");
 
   return MB_SUCCESS;
 }
@@ -996,16 +984,16 @@ ErrorCode ScdNCHelper::read_variables(std::vector<std::string>& var_names, std::
   std::vector<ReadNC::VarData> vsetdatas;
 
   ErrorCode rval = read_variables_setup(var_names, tstep_nums, vdatas, vsetdatas);
-  ERRORR(rval, "Trouble setting up read variable.");
+  CHK_ERR1(rval, "Trouble setting up to read variables");
 
   if (!vsetdatas.empty()) {
     rval = read_variables_to_set(vsetdatas, tstep_nums);
-    ERRORR(rval, "Trouble read variables to set.");
+    CHK_ERR1(rval, "Trouble reading variables to set");
   }
 
   if (!vdatas.empty()) {
     rval = read_scd_variables_to_nonset(vdatas, tstep_nums);
-    ERRORR(rval, "Trouble read variables to entities verts/edges/faces.");
+    CHK_ERR1(rval, "Trouble reading variables to verts/edges/faces");
   }
 
   return MB_SUCCESS;
@@ -1024,18 +1012,18 @@ ErrorCode ScdNCHelper::read_scd_variables_to_nonset_allocate(std::vector<ReadNC:
   // Get vertices
   Range verts;
   rval = mbImpl->get_entities_by_dimension(_fileSet, 0, verts);
-  ERRORR(rval, "Trouble getting vertices in current file set.");
+  CHK_ERR1(rval, "Trouble getting vertices in current file set");
   assert("Should only have a single vertex subrange, since they were read in one shot" &&
       verts.psize() == 1);
 
   Range edges;
   rval = mbImpl->get_entities_by_dimension(_fileSet, 1, edges);
-  ERRORR(rval, "Trouble getting edges in current file set.");
+  CHK_ERR1(rval, "Trouble getting edges in current file set");
 
   // Get faces
   Range faces;
   rval = mbImpl->get_entities_by_dimension(_fileSet, 2, faces);
-  ERRORR(rval, "Trouble getting faces in current file set.");
+  CHK_ERR1(rval, "Trouble getting faces in current file set");
   assert("Should only have a single face subrange, since they were read in one shot" &&
       faces.psize() == 1);
 
@@ -1045,7 +1033,7 @@ ErrorCode ScdNCHelper::read_scd_variables_to_nonset_allocate(std::vector<ReadNC:
   if (isParallel) {
     ParallelComm*& myPcomm = _readNC->myPcomm;
     rval = myPcomm->filter_pstatus(faces, PSTATUS_NOT_OWNED, PSTATUS_NOT, -1, &faces_owned);
-    ERRORR(rval, "Trouble getting owned faces in current file set.");
+    CHK_ERR1(rval, "Trouble getting owned faces in current file set");
   }
   else
     faces_owned = faces; // Not running in parallel, but still with MPI
@@ -1083,7 +1071,8 @@ ErrorCode ScdNCHelper::read_scd_variables_to_nonset_allocate(std::vector<ReadNC:
       case ReadNC::ENTLOCNSEDGE:
       case ReadNC::ENTLOCEWEDGE:
       case ReadNC::ENTLOCEDGE:
-        ERRORR(MB_NOT_IMPLEMENTED, "Reading edge data not implemented yet.");
+        // Not implemented yet, set a global error
+        SET_GLB_ERR(MB_NOT_IMPLEMENTED, "Reading edge data is not implemented yet");
         break;
       case ReadNC::ENTLOCFACE:
         // Faces
@@ -1098,27 +1087,27 @@ ErrorCode ScdNCHelper::read_scd_variables_to_nonset_allocate(std::vector<ReadNC:
 #endif
         break;
       default:
-        ERRORR(MB_FAILURE, "Unexpected entity location type.");
+        SET_ERR_STR(MB_FAILURE, "Unexpected entity location type for variable " << vdatas[i].varName);
     }
 
     for (unsigned int t = 0; t < tstep_nums.size(); t++) {
       dbgOut.tprintf(2, "Reading variable %s, time step %d\n", vdatas[i].varName.c_str(), tstep_nums[t]);
 
       if (tstep_nums[t] >= dimLens[tDim]) {
-        ERRORR(MB_INDEX_OUT_OF_RANGE, "Wrong value for a timestep number.");
+        SET_ERR_STR(MB_INDEX_OUT_OF_RANGE, "Wrong value for timestep number " << tstep_nums[t]);
       }
 
       // Get the tag to read into
       if (!vdatas[i].varTags[t]) {
         rval = get_tag_to_nonset(vdatas[i], tstep_nums[t], vdatas[i].varTags[t], vdatas[i].numLev);
-        ERRORR(rval, "Trouble getting tag.");
+        CHK_ERR1_STR(rval, "Trouble getting tag to non-set variable " << vdatas[i].varName);
       }
 
       // Get ptr to tag space
       void* data;
       int count;
       rval = mbImpl->tag_iterate(vdatas[i].varTags[t], range->begin(), range->end(), count, data);
-      ERRORR(rval, "Failed to get tag iterator.");
+      CHK_ERR1_STR(rval, "Failed to iterate tag for non-set variable " << vdatas[i].varName);
       assert((unsigned)count == range->size());
       vdatas[i].varDatas[t] = data;
     }
@@ -1137,7 +1126,7 @@ ErrorCode ScdNCHelper::read_scd_variables_to_nonset(std::vector<ReadNC::VarData>
   DebugOutput& dbgOut = _readNC->dbgOut;
 
   ErrorCode rval = read_scd_variables_to_nonset_allocate(vdatas, tstep_nums);
-  ERRORR(rval, "Trouble allocating space to read non-set variables.");
+  CHK_ERR1(rval, "Trouble allocating space to read non-set variables");
 
   // Finally, read into that space
   int success;
@@ -1163,7 +1152,8 @@ ErrorCode ScdNCHelper::read_scd_variables_to_nonset(std::vector<ReadNC::VarData>
           std::vector<char> tmpchardata(sz);
           success = NCFUNCAG(_vara_text)(_fileId, vdatas[i].varId, &vdatas[i].readStarts[0], &vdatas[i].readCounts[0],
                                         &tmpchardata[0]);
-          ERRORS(success, "Failed to read char data.");
+          if (success)
+            SET_ERR_STR(MB_FAILURE, "Failed to read byte/char data for variable " << vdatas[i].varName);
           if (vdatas[i].numLev > 1)
             // Transpose (lev, lat, lon) to (lat, lon, lev)
             kji_to_jik(ni, nj, nk, data, &tmpchardata[0]);
@@ -1178,7 +1168,8 @@ ErrorCode ScdNCHelper::read_scd_variables_to_nonset(std::vector<ReadNC::VarData>
           std::vector<int> tmpintdata(sz);
           success = NCFUNCAG(_vara_int)(_fileId, vdatas[i].varId, &vdatas[i].readStarts[0], &vdatas[i].readCounts[0],
                                         &tmpintdata[0]);
-          ERRORS(success, "Failed to read int data.");
+          if (success)
+            SET_ERR_STR(MB_FAILURE, "Failed to read short/int data for variable " << vdatas[i].varName);
           if (vdatas[i].numLev > 1)
             // Transpose (lev, lat, lon) to (lat, lon, lev)
             kji_to_jik(ni, nj, nk, data, &tmpintdata[0]);
@@ -1193,7 +1184,8 @@ ErrorCode ScdNCHelper::read_scd_variables_to_nonset(std::vector<ReadNC::VarData>
           std::vector<double> tmpdoubledata(sz);
           success = NCFUNCAG(_vara_double)(_fileId, vdatas[i].varId, &vdatas[i].readStarts[0], &vdatas[i].readCounts[0],
                                           &tmpdoubledata[0]);
-          ERRORS(success, "Failed to read double data.");
+          if (success)
+            SET_ERR_STR(MB_FAILURE, "Failed to read float/double data for variable " << vdatas[i].varName);
           if (vdatas[i].numLev > 1)
             // Transpose (lev, lat, lon) to (lat, lon, lev)
             kji_to_jik(ni, nj, nk, data, &tmpdoubledata[0]);
@@ -1204,7 +1196,7 @@ ErrorCode ScdNCHelper::read_scd_variables_to_nonset(std::vector<ReadNC::VarData>
           break;
         }
         default:
-          ERRORR(MB_FAILURE, "Unexpected variable data type.");
+          SET_ERR_STR(MB_FAILURE, "Unexpected data type for variable " << vdatas[i].varName);
       }
     }
   }
@@ -1225,7 +1217,7 @@ ErrorCode ScdNCHelper::create_quad_coordinate_tag() {
 
   Range ents;
   ErrorCode rval = mbImpl->get_entities_by_type(_fileSet, moab::MBQUAD, ents);
-  ERRORR(rval, "Trouble getting QUAD entity.");
+  CHK_ERR1(rval, "Trouble getting quads");
 
   std::size_t numOwnedEnts = 0;
 #ifdef USE_MPI
@@ -1234,7 +1226,7 @@ ErrorCode ScdNCHelper::create_quad_coordinate_tag() {
   if (isParallel) {
     ParallelComm*& myPcomm = _readNC->myPcomm;
     rval = myPcomm->filter_pstatus(ents, PSTATUS_NOT_OWNED, PSTATUS_NOT, -1, &ents_owned);
-    ERRORR(rval, "Trouble getting owned QUAD entity.");
+    CHK_ERR1(rval, "Trouble getting owned quads");
     numOwnedEnts = ents_owned.size();
   }
   else {
@@ -1262,7 +1254,7 @@ ErrorCode ScdNCHelper::create_quad_coordinate_tag() {
   std::string tag_name = "COORDS";
   Tag tagh = 0;
   rval = mbImpl->tag_get_handle(tag_name.c_str(), 3, MB_TYPE_DOUBLE, tagh, MB_TAG_DENSE | MB_TAG_CREAT);
-  ERRORR(rval, "Trouble creating COORDS tag.");
+  CHK_ERR1(rval, "Trouble creating COORDS tag");
 
   void *data;
   int count;
@@ -1271,7 +1263,7 @@ ErrorCode ScdNCHelper::create_quad_coordinate_tag() {
 #else
   rval = mbImpl->tag_iterate(tagh, ents.begin(), ents.end(), count, data);
 #endif
-  ERRORR(rval, "Failed to get COORDS tag iterator.");
+  CHK_ERR1(rval, "Failed to iterate COORDS tag on quads");
   assert(count == (int)numOwnedEnts);
   double* quad_data = (double*) data;
   std::copy(coords.begin(), coords.end(), quad_data);
@@ -1285,11 +1277,11 @@ ErrorCode UcdNCHelper::read_variables(std::vector<std::string>& var_names, std::
   std::vector<ReadNC::VarData> vsetdatas;
 
   ErrorCode rval = read_variables_setup(var_names, tstep_nums, vdatas, vsetdatas);
-  ERRORR(rval, "Trouble setting up read variable.");
+  CHK_ERR1(rval, "Trouble setting up to read variables");
 
   if (!vsetdatas.empty()) {
     rval = read_variables_to_set(vsetdatas, tstep_nums);
-    ERRORR(rval, "Trouble read variables to set.");
+    CHK_ERR1(rval, "Trouble reading variables to set");
   }
 
   if (!vdatas.empty()) {
@@ -1300,7 +1292,7 @@ ErrorCode UcdNCHelper::read_variables(std::vector<std::string>& var_names, std::
     // Without pnetcdf support, we will use old read
     rval = read_ucd_variables_to_nonset(vdatas, tstep_nums);
 #endif
-    ERRORR(rval, "Trouble read variables to entities verts/edges/faces.");
+    CHK_ERR1(rval, "Trouble reading variables to verts/edges/faces");
   }
 
   return MB_SUCCESS;

diff --git a/src/io/ReadNC.cpp b/src/io/ReadNC.cpp
index 64d67ab..9d7a49b 100644
--- a/src/io/ReadNC.cpp
+++ b/src/io/ReadNC.cpp
@@ -5,12 +5,6 @@
 #include "MBTagConventions.hpp"
 #include "moab/FileOptions.hpp"
 
-#define ERRORR(rval, str) \
-  if (MB_SUCCESS != rval) { readMeshIface->report_error("%s", str); return rval; }
-
-#define ERRORS(err, str) \
-  if (err) { readMeshIface->report_error("%s", str); return MB_FAILURE; }
-
 namespace moab {
 
 ReaderIface* ReadNC::factory(Interface* iface)
@@ -51,15 +45,14 @@ ErrorCode ReadNC::load_file(const char* file_name, const EntityHandle* file_set,
   // Get and cache predefined tag handles
   int dum_val = 0;
   rval = mbImpl->tag_get_handle(GLOBAL_ID_TAG_NAME, 1, MB_TYPE_INTEGER, mGlobalIdTag, MB_TAG_DENSE | MB_TAG_CREAT, &dum_val);
-  if (MB_SUCCESS != rval)
-    return rval;
+  CHK_ERR1(rval, "Trouble getting global ID tag");
 
   // Store the pointer to the tag; if not null, set when global id tag
   // is set too, with the same data, duplicated
   mpFileIdTag = file_id_tag;
 
   rval = parse_options(opts, var_names, tstep_nums, tstep_vals);
-  ERRORR(rval, "Trouble parsing option string.");
+  CHK_ERR1(rval, "Trouble parsing option string");
 
   // Open the file
   dbgOut.tprintf(1, "Opening file %s\n", file_name);
@@ -74,21 +67,21 @@ ErrorCode ReadNC::load_file(const char* file_name, const EntityHandle* file_set,
 #else
   success = NCFUNC(open)(file_name, 0, &fileId);
 #endif
-
-  ERRORS(success, "Trouble opening file.");
+  if (success)
+    SET_ERR_STR(MB_FAILURE, "Trouble opening file " << file_name);
 
   // Read the header (num dimensions, dimensions, num variables, global attribs)
   rval = read_header();
-  ERRORR(rval, "Trouble reading file header.");
+  CHK_ERR1(rval, "Trouble reading file header");
 
   // Make sure there's a file set to put things in
   EntityHandle tmp_set;
   if (noMesh && !file_set) {
-    ERRORR(MB_FAILURE, "NOMESH option requires non-NULL file set on input.");
+    SET_ERR(MB_FAILURE, "NOMESH option requires non-NULL file set on input");
   }
   else if (!file_set || (file_set && *file_set == 0)) {
     rval = mbImpl->create_meshset(MESHSET_SET, tmp_set);
-    ERRORR(rval, "Trouble creating file set.");
+    CHK_ERR1(rval, "Trouble creating file set");
   }
   else
     tmp_set = *file_set;
@@ -105,17 +98,17 @@ ErrorCode ReadNC::load_file(const char* file_name, const EntityHandle* file_set,
   // Get appropriate NC helper instance based on information read from the header
   myHelper = NCHelper::get_nc_helper(this, fileId, opts, tmp_set);
   if (NULL == myHelper) {
-    ERRORR(MB_FAILURE, "Failed to get NCHelper class instance.");
+    SET_ERR(MB_FAILURE, "Failed to get NCHelper class instance");
   }
 
   // Initialize mesh values
   rval = myHelper->init_mesh_vals();
-  ERRORR(rval, "Trouble initializing mesh values.");
+  CHK_ERR1(rval, "Trouble initializing mesh values");
 
   // Check existing mesh from last read
   if (noMesh && !noVars) {
     rval = myHelper->check_existing_mesh();
-    ERRORR(rval, "Trouble checking mesh from last read.");
+    CHK_ERR1(rval, "Trouble checking mesh from last read");
   }
 
   // Create some conventional tags, e.g. __NUM_DIMS
@@ -126,7 +119,7 @@ ErrorCode ReadNC::load_file(const char* file_name, const EntityHandle* file_set,
   int def_val = 0;
   rval = mbImpl->tag_get_handle("__CONV_TAGS_CREATED", 1, MB_TYPE_INTEGER, convTagsCreated,
                                 MB_TAG_SPARSE | MB_TAG_CREAT, &def_val);
-  ERRORR(rval, "Trouble getting _CONV_TAGS_CREATED tag.");
+  CHK_ERR1(rval, "Trouble getting _CONV_TAGS_CREATED tag");
   int create_conv_tags_flag = 0;
   rval = mbImpl->tag_get_data(convTagsCreated, &tmp_set, 1, &create_conv_tags_flag);
   // The first read to the file set
@@ -134,14 +127,14 @@ ErrorCode ReadNC::load_file(const char* file_name, const EntityHandle* file_set,
     // Read dimensions (coordinate variables) by default to create tags like __<var_name>_DIMS
     // This is done only once (assume that all files read to the file set have the same dimensions)
     rval = myHelper->read_variables(dimNames, tstep_nums);
-    ERRORR(rval, "Trouble reading dimensions.");
+    CHK_ERR1(rval, "Trouble reading dimensions");
 
     rval = myHelper->create_conventional_tags(tstep_nums);
-    ERRORR(rval, "Trouble creating NC conventional tags.");
+    CHK_ERR1(rval, "Trouble creating NC conventional tags");
 
     create_conv_tags_flag = 1;
     rval = mbImpl->tag_set_data(convTagsCreated, &tmp_set, 1, &create_conv_tags_flag);
-    ERRORR(rval, "Trouble setting data for _CONV_TAGS_CREATED tag.");
+    CHK_ERR1(rval, "Trouble setting data to _CONV_TAGS_CREATED tag");
   }
   // Another read to the file set
   else {
@@ -149,7 +142,7 @@ ErrorCode ReadNC::load_file(const char* file_name, const EntityHandle* file_set,
       // If timesteps spread across files, merge time values read
       // from current file to existing time tag
       rval = myHelper->update_time_tag_vals();
-      ERRORR(rval, "Trouble updating time tag values.");
+      CHK_ERR1(rval, "Trouble updating time tag values");
     }
   }
 
@@ -157,7 +150,7 @@ ErrorCode ReadNC::load_file(const char* file_name, const EntityHandle* file_set,
   Range faces;
   if (!noMesh) {
     rval = myHelper->create_mesh(faces);
-    ERRORR(rval, "Trouble creating mesh.");
+    CHK_ERR1(rval, "Trouble creating mesh");
   }
 
   // Read specified variables onto grid
@@ -165,7 +158,7 @@ ErrorCode ReadNC::load_file(const char* file_name, const EntityHandle* file_set,
     if (var_names.empty()) {
       // If VARIABLE option is missing, read all variables
       rval = myHelper->read_variables(var_names, tstep_nums);
-      ERRORR(rval, "Trouble reading all variables.");
+      CHK_ERR1(rval, "Trouble reading all variables");
     }
     else {
       // Exclude dimensions that are read to the file set by default
@@ -177,7 +170,7 @@ ErrorCode ReadNC::load_file(const char* file_name, const EntityHandle* file_set,
 
       if (!non_dim_var_names.empty()) {
         rval = myHelper->read_variables(non_dim_var_names, tstep_nums);
-        ERRORR(rval, "Trouble reading specified variables.");
+        CHK_ERR1(rval, "Trouble reading specified variables");
       }
     }
   }
@@ -187,17 +180,17 @@ ErrorCode ReadNC::load_file(const char* file_name, const EntityHandle* file_set,
   if (isParallel) {
     EntityHandle partn_set;
     rval = mbImpl->create_meshset(MESHSET_SET, partn_set);
-    ERRORR(rval, "Trouble creating partition set.");
+    CHK_ERR1(rval, "Trouble creating partition set");
 
     rval = mbImpl->add_entities(partn_set, faces);
-    ERRORR(rval, "Couldn't add new faces to partition set.");
+    CHK_ERR1(rval, "Couldn't add new faces to partition set");
 
     Range verts;
     rval = mbImpl->get_connectivity(faces, verts);
-    ERRORR(rval, "Couldn't get verts of faces.");
+    CHK_ERR1(rval, "Couldn't get verts of faces");
 
     rval = mbImpl->add_entities(partn_set, verts);
-    ERRORR(rval, "Couldn't add new verts to partition set.");
+    CHK_ERR1(rval, "Couldn't add new verts to partition set");
 
     myPcomm->partition_sets().insert(partn_set);
 
@@ -205,8 +198,7 @@ ErrorCode ReadNC::load_file(const char* file_name, const EntityHandle* file_set,
     Tag part_tag = myPcomm->partition_tag();
     int dum_rank = myPcomm->proc_config().proc_rank();
     rval = mbImpl->tag_set_data(part_tag, &partn_set, 1, &dum_rank);
-    if (MB_SUCCESS != rval)
-      return rval;
+    CHK_ERR1(rval, "Trouble writing partition tag name on partition set");
   }
 #endif
 
@@ -215,7 +207,8 @@ ErrorCode ReadNC::load_file(const char* file_name, const EntityHandle* file_set,
 
   // Close the file
   success = NCFUNC(close)(fileId);
-  ERRORS(success, "Trouble closing file.");
+  if (success)
+    SET_ERR(MB_FAILURE, "Trouble closing file");
 
   return MB_SUCCESS;
 }
@@ -279,20 +272,17 @@ ErrorCode ReadNC::parse_options(const FileOptions& opts, std::vector<std::string
 
   rval = opts.get_int_option("GATHER_SET", 0, gatherSetRank);
   if (MB_TYPE_OUT_OF_RANGE == rval) {
-    readMeshIface->report_error("Invalid value for GATHER_SET option");
-    return rval;
+    SET_ERR(rval, "Invalid value for GATHER_SET option");
   }
 
   rval = opts.get_int_option("TIMESTEPBASE", 0, tStepBase);
   if (MB_TYPE_OUT_OF_RANGE == rval) {
-    readMeshIface->report_error("Invalid value for TIMESTEPBASE option");
-    return rval;
+    SET_ERR(rval, "Invalid value for TIMESTEPBASE option");
   }
 
   rval = opts.get_int_option("TRIVIAL_PARTITION_SHIFT", 1, trivialPartitionShift);
   if (MB_TYPE_OUT_OF_RANGE == rval) {
-    readMeshIface->report_error("Invalid value for TRIVIAL_PARTITION_SHIFT option");
-    return rval;
+    SET_ERR(rval, "Invalid value for TRIVIAL_PARTITION_SHIFT option");
   }
 
 #ifdef USE_MPI
@@ -307,8 +297,7 @@ ErrorCode ReadNC::parse_options(const FileOptions& opts, std::vector<std::string
   int pcomm_no = 0;
   rval = opts.get_int_option("PARALLEL_COMM", pcomm_no);
   if (MB_TYPE_OUT_OF_RANGE == rval) {
-    readMeshIface->report_error("Invalid value for PARALLEL_COMM option");
-    return rval;
+    SET_ERR(rval, "Invalid value for PARALLEL_COMM option");
   }
   myPcomm = ParallelComm::get_pcomm(mbImpl, pcomm_no);
   if (0 == myPcomm) {
@@ -320,8 +309,7 @@ ErrorCode ReadNC::parse_options(const FileOptions& opts, std::vector<std::string
   int dum;
   rval = opts.match_option("PARTITION_METHOD", ScdParData::PartitionMethodNames, dum);
   if (MB_FAILURE == rval) {
-    readMeshIface->report_error("Unknown partition method specified");
-    return rval;
+    SET_ERR(rval, "Unknown partition method specified");
   }
   else if (MB_ENTITY_NOT_FOUND == rval)
     partMethod = ScdParData::ALLJORKORI;
@@ -340,21 +328,22 @@ ErrorCode ReadNC::read_header()
   int numgatts;
   int success;
   success = NCFUNC(inq_natts )(fileId, &numgatts);
-  ERRORS(success, "Couldn't get number of global attributes.");
+  if (success)
+    SET_ERR(MB_FAILURE, "Couldn't get number of global attributes");
 
   // Read attributes into globalAtts
   ErrorCode result = get_attributes(NC_GLOBAL, numgatts, globalAtts);
-  ERRORR(result, "Trouble getting attributes.");
+  CHK_ERR1(result, "Trouble getting global attributes");
   dbgOut.tprintf(1, "Read %u attributes\n", (unsigned int) globalAtts.size());
 
   // Read in dimensions into dimNames and dimLens
   result = get_dimensions(fileId, dimNames, dimLens);
-  ERRORR(result, "Trouble getting dimensions.");
+  CHK_ERR1(result, "Trouble getting dimensions");
   dbgOut.tprintf(1, "Read %u dimensions\n", (unsigned int) dimNames.size());
 
   // Read in variables into varInfo
   result = get_variables();
-  ERRORR(result, "Trouble getting variables.");
+  CHK_ERR1(result, "Trouble getting variables");
   dbgOut.tprintf(1, "Read %u variables\n", (unsigned int) varInfo.size());
 
   return MB_SUCCESS;
@@ -367,12 +356,14 @@ ErrorCode ReadNC::get_attributes(int var_id, int num_atts, std::map<std::string,
   for (int i = 0; i < num_atts; i++) {
     // Get the name
     int success = NCFUNC(inq_attname)(fileId, var_id, i, dum_name);
-    ERRORS(success, "Trouble getting attribute name.");
+    if (success)
+      SET_ERR(MB_FAILURE, "Trouble getting attribute name");
 
     AttData &data = atts[std::string(dum_name)];
     data.attName = std::string(dum_name);
     success = NCFUNC(inq_att)(fileId, var_id, dum_name, &data.attDataType, &data.attLen);
-    ERRORS(success, "Trouble getting attribute info.");
+    if (success)
+      SET_ERR_STR(MB_FAILURE, "Trouble getting info for attribute " << data.attName);
     data.attVarId = var_id;
 
     dbgOut.tprintf(2, "%sAttribute %s: length=%u, varId=%d, type=%d\n", (prefix ? prefix : ""), data.attName.c_str(),
@@ -387,11 +378,11 @@ ErrorCode ReadNC::get_dimensions(int file_id, std::vector<std::string>& dim_name
   // Get the number of dimensions
   int num_dims;
   int success = NCFUNC(inq_ndims)(file_id, &num_dims);
-  ERRORS(success, "Trouble getting number of dimensions.");
+  if (success)
+    SET_ERR(MB_FAILURE, "Trouble getting number of dimensions");
 
   if (num_dims > NC_MAX_DIMS) {
-    readMeshIface->report_error("ReadNC: File contains %d dims but NetCDF library supports only %d\n", num_dims, (int) NC_MAX_DIMS);
-    return MB_FAILURE;
+    SET_ERR_STR(MB_FAILURE, "ReadNC: File contains " << num_dims << " dims but NetCDF library supports only " << NC_MAX_DIMS);
   }
 
   char dim_name[NC_MAX_NAME + 1];
@@ -401,7 +392,8 @@ ErrorCode ReadNC::get_dimensions(int file_id, std::vector<std::string>& dim_name
 
   for (int i = 0; i < num_dims; i++) {
     success = NCFUNC(inq_dim)(file_id, i, dim_name, &dim_len);
-    ERRORS(success, "Trouble getting dimension info.");
+    if (success)
+      SET_ERR(MB_FAILURE, "Trouble getting dimension info");
 
     dim_names[i] = std::string(dim_name);
     dim_lens[i] = dim_len;
@@ -428,11 +420,11 @@ ErrorCode ReadNC::get_variables()
   // Get the number of variables
   int num_vars;
   int success = NCFUNC(inq_nvars)(fileId, &num_vars);
-  ERRORS(success, "Trouble getting number of variables.");
+  if (success)
+    SET_ERR(MB_FAILURE, "Trouble getting number of variables");
 
   if (num_vars > NC_MAX_VARS) {
-    readMeshIface->report_error("ReadNC: File contains %d vars but NetCDF library supports only %d\n", num_vars, (int) NC_MAX_VARS);
-    return MB_FAILURE;
+    SET_ERR_STR(MB_FAILURE, "ReadNC: File contains " << num_vars << " vars but NetCDF library supports only " << NC_MAX_VARS);
   }
 
   char var_name[NC_MAX_NAME + 1];
@@ -441,7 +433,8 @@ ErrorCode ReadNC::get_variables()
   for (int i = 0; i < num_vars; i++) {
     // Get the name first, so we can allocate a map iterate for this var
     success = NCFUNC(inq_varname )(fileId, i, var_name);
-    ERRORS(success, "Trouble getting var name.");
+    if (success)
+      SET_ERR(MB_FAILURE, "Trouble getting variable name");
     VarData &data = varInfo[std::string(var_name)];
     data.varName = std::string(var_name);
     data.varId = i;
@@ -449,26 +442,30 @@ ErrorCode ReadNC::get_variables()
 
     // Get the data type
     success = NCFUNC(inq_vartype)(fileId, i, &data.varDataType);
-    ERRORS(success, "Trouble getting variable data type.");
+    if (success)
+      SET_ERR_STR(MB_FAILURE, "Trouble getting data type for variable " << data.varName);
 
     // Get the number of dimensions, then the dimensions
     success = NCFUNC(inq_varndims)(fileId, i, &var_ndims);
-    ERRORS(success, "Trouble getting number of dims of a variable.");
+    if (success)
+      SET_ERR_STR(MB_FAILURE, "Trouble getting number of dims for variable " << data.varName);
     data.varDims.resize(var_ndims);
 
     success = NCFUNC(inq_vardimid)(fileId, i, &data.varDims[0]);
-    ERRORS(success, "Trouble getting variable dimensions.");
+    if (success)
+      SET_ERR_STR(MB_FAILURE, "Trouble getting dimensions for variable " << data.varName);
 
     // Finally, get the number of attributes, then the attributes
     success = NCFUNC(inq_varnatts)(fileId, i, &data.numAtts);
-    ERRORS(success, "Trouble getting number of dims of a variable.");
+    if (success)
+      SET_ERR_STR(MB_FAILURE, "Trouble getting number of dims for variable " << data.varName);
 
     // Print debug info here so attribute info comes afterwards
     dbgOut.tprintf(2, "Variable %s: Id=%d, numAtts=%d, datatype=%d, num_dims=%u\n", data.varName.c_str(), data.varId, data.numAtts,
         data.varDataType, (unsigned int) data.varDims.size());
 
     ErrorCode rval = get_attributes(i, data.numAtts, data.varAtts, "   ");
-    ERRORR(rval, "Trouble getting attributes for a variable.");
+    CHK_ERR1_STR(rval, "Trouble getting attributes for variable " << data.varName);
   }
 
   return MB_SUCCESS;

Repository URL: https://bitbucket.org/fathomteam/moab/

--

This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.


More information about the moab-dev mailing list