USGS

Isis 3.0 Object Programmers' Reference

Home

IException.cpp
Go to the documentation of this file.
1 
24 #include "IsisDebug.h"
25 #include "IException.h"
26 
27 #include <stdlib.h>
28 
29 #include <algorithm>
30 #include <cstring>
31 #include <iostream>
32 #include <sstream>
33 #include <string>
34 
35 #include <QList>
36 
37 #include "Application.h"
38 #include "Preference.h"
39 #include "Pvl.h"
40 
41 using namespace std;
42 
43 namespace Isis {
56  IException::IException() {
57  m_what = NULL;
58  m_errorType = Unknown;
59  m_message = NULL;
60  m_fileName = NULL;
61  m_previousExceptions = NULL;
62  m_lineNumber = -1;
63 
64  m_what = buildWhat();
65  }
66 
67 
88  IException::IException(ErrorType type, const QString &message,
89  const char *fileName, int lineNumber) {
90  m_what = NULL;
91  m_message = NULL;
92  m_fileName = NULL;
93  m_previousExceptions = NULL;
94 
95  m_errorType = type;
96  m_message = new QString(QString(message).trimmed());
97  m_fileName = new QString(fileName);
98  m_lineNumber = lineNumber;
99 
100  deleteEmptyMemberStrings();
101 
102  m_what = buildWhat();
103  }
104 
105 
126  IException::IException(ErrorType type, const char *message,
127  const char *fileName, int lineNumber) {
128  m_what = NULL;
129  m_message = NULL;
130  m_fileName = NULL;
131  m_previousExceptions = NULL;
132 
133  m_errorType = type;
134  m_message = new QString(QString(message).trimmed());
135  m_fileName = new QString(fileName);
136  m_lineNumber = lineNumber;
137 
138  deleteEmptyMemberStrings();
139 
140  m_what = buildWhat();
141  }
142 
143 
164  IException::IException(ErrorType type, const std::string &message,
165  const char *fileName, int lineNumber) {
166  m_what = NULL;
167  m_message = NULL;
168  m_fileName = NULL;
169  m_previousExceptions = NULL;
170 
171  m_errorType = type;
172  m_message = new QString(QString(message.c_str()).trimmed());
173  m_fileName = new QString(fileName);
174  m_lineNumber = lineNumber;
175 
176  deleteEmptyMemberStrings();
177 
178  m_what = buildWhat();
179  }
180 
181 
212  IException::IException(const IException &caughtException,
213  ErrorType type, const char *message,
214  const char *fileName, int lineNumber) {
215  m_what = NULL;
216  m_message = NULL;
217  m_fileName = NULL;
218  m_previousExceptions = NULL;
219 
220  m_errorType = type;
221  m_message = new QString(QString(message).trimmed());
222  m_fileName = new QString(fileName);
223  m_lineNumber = lineNumber;
224 
225  deleteEmptyMemberStrings();
226 
227  append(caughtException);
228  }
229 
230 
260  IException::IException(const IException &caughtException,
261  ErrorType type, const std::string &message,
262  const char *fileName, int lineNumber) {
263  m_what = NULL;
264  m_message = NULL;
265  m_fileName = NULL;
266  m_previousExceptions = NULL;
267 
268  m_errorType = type;
269  m_message = new QString(QString(message.c_str()).trimmed());
270  m_fileName = new QString(fileName);
271  m_lineNumber = lineNumber;
272 
273  deleteEmptyMemberStrings();
274 
275  append(caughtException);
276  }
277 
278 
307  IException::IException(const IException &caughtException,
308  ErrorType type, const QString &message,
309  const char *fileName, int lineNumber) {
310  m_what = NULL;
311  m_message = NULL;
312  m_fileName = NULL;
313  m_previousExceptions = NULL;
314 
315  m_errorType = type;
316  m_message = new QString(message.trimmed());
317  m_fileName = new QString(fileName);
318  m_lineNumber = lineNumber;
319 
320  deleteEmptyMemberStrings();
321 
322  append(caughtException);
323  }
324 
325 
331  IException::IException(const IException &other) : exception(other) {
332  m_what = NULL;
333  m_message = NULL;
334  m_fileName = NULL;
335  m_previousExceptions = NULL;
336 
337  m_errorType = other.m_errorType;
338  m_lineNumber = other.m_lineNumber;
339 
340  if (other.m_what) {
341  int length = strlen(other.m_what);
342  m_what = new char[length + 1];
343  strncpy(m_what, other.m_what, length);
344  m_what[length] = '\0';
345  }
346 
347  if (other.m_message) {
348  m_message = new QString(*other.m_message);
349  }
350 
351  if (other.m_fileName) {
352  m_fileName = new QString(*other.m_fileName);
353  }
354 
355  if (other.m_previousExceptions) {
357  }
358  }
359 
360 
366  delete [] m_what;
367  m_what = NULL;
368 
370 
371  delete m_message;
372  m_message = NULL;
373 
374  delete m_fileName;
375  m_fileName = NULL;
376 
377  m_lineNumber = -1;
378 
379  delete m_previousExceptions;
380  m_previousExceptions = NULL;
381  }
382 
383 
391  const char *IException::what() const throw() {
392  return m_what;
393  }
394 
425  void IException::append(const IException &exceptionSource) {
426  if (!m_previousExceptions) {
428  }
429 
430  if (exceptionSource.m_previousExceptions) {
431  m_previousExceptions->append(*exceptionSource.m_previousExceptions);
432  }
433 
434  m_previousExceptions->append(exceptionSource);
435 
436  delete [] m_what;
437  m_what = NULL;
438  m_what = buildWhat();
439  }
440 
447  return m_errorType;
448  }
449 
450 
461  void IException::print() const {
462  QString errorString = toString();
463  if (errorString != "")
464  cerr << errorString.toAscii().data() << endl;
465  }
466 
467 
477  void IException::print(bool printFileInfo) const {
478  QString errorString = toString(printFileInfo);
479  if (errorString != "")
480  cerr << errorString.toAscii().data() << endl;
481  }
482 
483 
492  Pvl errors;
493 
494  QList<IException> exceptionsToConvert;
495 
497  exceptionsToConvert.append(*m_previousExceptions);
498  }
499  exceptionsToConvert.append(*this);
500 
501  for (int exceptionIndex = exceptionsToConvert.size() - 1;
502  exceptionIndex >= 0;
503  exceptionIndex--) {
504  const IException &exception(exceptionsToConvert.at(exceptionIndex));
505 
506  bool exceptionIsBlank = true;
507  PvlGroup errGroup("Error");
508 
509  errGroup += PvlKeyword("Program", Application::Name());
510 
511  if (exception.m_errorType != Unknown) {
512  errGroup += PvlKeyword("Class",
513  errorTypeToString(exception.m_errorType));
514  exceptionIsBlank = false;
515  }
516 
517  errGroup += PvlKeyword("Code", Isis::toString(exception.m_errorType));
518 
519  if (exception.m_message) {
520  exceptionIsBlank = false;
521  QString message(*exception.m_message);
522 
523  if (message.size() && message[message.size() - 1] == '.')
524  message = message.mid(0, message.size() - 1);
525  errGroup += PvlKeyword("Message", message);
526  }
527 
528  if (exception.m_fileName) {
529  exceptionIsBlank = false;
530  errGroup += PvlKeyword("File", *exception.m_fileName);
531 
532  if (exception.m_lineNumber != -1)
533  errGroup += PvlKeyword("Line", Isis::toString(exception.m_lineNumber));
534  }
535 
536  if (!exceptionIsBlank)
537  errors.addGroup(errGroup);
538  }
539 
540  return errors;
541  }
542 
543 
553  QString IException::toString() const {
554  bool reportFileLine = true;
555 
556  if (Preference::Preferences().hasGroup("ErrorFacility")) {
557  PvlGroup &errorFacility =
558  Preference::Preferences().findGroup("ErrorFacility");
559  if (errorFacility.hasKeyword("FileLine")) {
560  QString fileLine = errorFacility["FileLine"][0];
561  reportFileLine = (fileLine.toUpper() == "ON");
562  }
563  }
564 
565  return toString(reportFileLine);
566  }
567 
568 
580  QString IException::toString(bool includeFileInfo) const {
581  QString result;
582 
583  bool usePvlFormat = false;
584 
585  if (Preference::Preferences().hasGroup("ErrorFacility")) {
586  PvlGroup &errorFacility =
587  Preference::Preferences().findGroup("ErrorFacility");
588  if (errorFacility.hasKeyword("Format")) {
589  QString format = errorFacility["Format"][0];
590  usePvlFormat = (format.toUpper() == "PVL");
591  }
592  }
593 
594  if (usePvlFormat) {
595  Pvl errors = toPvl();
596 
597  if (errors.groups() != 0) {
598  stringstream stringStream;
599  stringStream << errors;
600  result = stringStream.str().c_str();
601  }
602  }
603  else {
604  QList<IException> exceptionsToConvert;
605 
607  exceptionsToConvert.append(*m_previousExceptions);
608  }
609  exceptionsToConvert.append(*this);
610 
611  for (int exceptionIndex = exceptionsToConvert.size() - 1;
612  exceptionIndex >= 0;
613  exceptionIndex--) {
614  const IException &exception(exceptionsToConvert.at(exceptionIndex));
615 
616  // Don't put **ERROR** if there is no message or type
617  if (exception.m_errorType != Unknown || exception.m_message) {
618  result += "**" + errorTypeToString(exception.m_errorType) + "**";
619  }
620 
621  bool needsPeriod = false;
622  if (exception.m_message) {
623  QString message(*exception.m_message);
624 
625  if (message.size() && message[message.size() - 1] == '.')
626  message = message.mid(0, message.size() - 1);
627  // There is always a **TYPE** already in the string, so prefix the
628  // message with a space.
629  result += " " + message;
630  needsPeriod = true;
631  }
632 
633  if(includeFileInfo && exception.m_fileName) {
634  result += " in " + *exception.m_fileName;
635  if (exception.m_lineNumber != -1)
636  result += " at " + Isis::toString(exception.m_lineNumber);
637  needsPeriod = true;
638  }
639 
640  if (needsPeriod)
641  result += ".";
642 
643  if (result.size() && result[result.size() - 1] != '\n')
644  result += "\n";
645  }
646  }
647 
648  return result.trimmed();
649  }
650 
651 
659  std::swap(m_what, other.m_what);
660  std::swap(m_errorType, other.m_errorType);
661  std::swap(m_message, other.m_message);
662  std::swap(m_fileName, other.m_fileName);
663  std::swap(m_lineNumber, other.m_lineNumber);
664  std::swap(m_previousExceptions, other.m_previousExceptions);
665  }
666 
667 
676  IException copy(rhs);
677  swap(copy);
678 
679  return *this;
680  }
681 
682 
690  vector<string> theStack;
691  StackTrace::GetStackTrace(&theStack);
692  QString message;
693 
694  for(unsigned int i = 1; i < theStack.size(); i++) {
695  message += (theStack[i] + "\n").c_str();
696  }
697 
698  IException result;
699  if (theStack.size() != 0) {
700  result = IException(Unknown, message, NULL, -1);
701  }
702 
703  return result;
704  }
705 
706 
715  QString result;
716 
717  switch(type) {
718  case User:
719  result = "USER ERROR";
720  break;
721  case Programmer:
722  result = "PROGRAMMER ERROR";
723  break;
724  case Io:
725  result = "I/O ERROR";
726  break;
727  case Unknown:
728  result = "ERROR";
729  break;
730  }
731 
732  return result;
733  }
734 
735 
744  const QString &string) {
745  ErrorType result = Unknown;
746 
747  if(string == "USER ERROR")
748  result = User;
749  else if(string == "PROGRAMMER ERROR")
750  result = Programmer;
751  else if(string == "I/O ERROR")
752  result = Io;
753 
754  return result;
755  }
756 
757 
766  char *IException::buildWhat() const {
767  QString whatStr = toString();
768 
769  char *result = new char[whatStr.size() + 1];
770  strncpy(result, whatStr.toAscii().data(), whatStr.size());
771  result[whatStr.size()] = '\0';
772 
773  return result;
774  }
775 
776 
783  if (m_message->size() == 0) {
784  delete m_message;
785  m_message = NULL;
786  }
787 
788  if (m_fileName->size() == 0) {
789  delete m_fileName;
790  m_fileName = NULL;
791  }
792  }
793 }
794