Isis 3 Programmer Reference
IException.cpp
1
6/* SPDX-License-Identifier: CC0-1.0 */
7#include "IException.h"
8
9#include <stdlib.h>
10
11#include <algorithm>
12#include <cstring>
13#include <iostream>
14#include <sstream>
15#include <string>
16
17#include <QList>
18
19#include "Application.h"
20#include "Preference.h"
21#include "Pvl.h"
22
23using namespace std;
24
25namespace Isis {
39 m_what = NULL;
41 m_message = NULL;
42 m_fileName = NULL;
44 m_lineNumber = -1;
45
46 m_what = buildWhat();
47 }
48
49
70 IException::IException(ErrorType type, const QString &message,
71 const char *fileName, int lineNumber) {
72 m_what = NULL;
73 m_message = NULL;
74 m_fileName = NULL;
76
77 m_errorType = type;
78 m_message = new QString(QString(message).trimmed());
79 m_fileName = new QString(fileName);
80 m_lineNumber = lineNumber;
81
83
84 m_what = buildWhat();
85 }
86
87
108 IException::IException(ErrorType type, const char *message,
109 const char *fileName, int lineNumber) {
110 m_what = NULL;
111 m_message = NULL;
112 m_fileName = NULL;
114
115 m_errorType = type;
116 m_message = new QString(QString(message).trimmed());
117 m_fileName = new QString(fileName);
118 m_lineNumber = lineNumber;
119
121
122 m_what = buildWhat();
123 }
124
125
146 IException::IException(ErrorType type, const std::string &message,
147 const char *fileName, int lineNumber) {
148 m_what = NULL;
149 m_message = NULL;
150 m_fileName = NULL;
152
153 m_errorType = type;
154 m_message = new QString(QString(message.c_str()).trimmed());
155 m_fileName = new QString(fileName);
156 m_lineNumber = lineNumber;
157
159
160 m_what = buildWhat();
161 }
162
163
194 IException::IException(const IException &caughtException,
195 ErrorType type, const char *message,
196 const char *fileName, int lineNumber) {
197 m_what = NULL;
198 m_message = NULL;
199 m_fileName = NULL;
201
202 m_errorType = type;
203 m_message = new QString(QString(message).trimmed());
204 m_fileName = new QString(fileName);
205 m_lineNumber = lineNumber;
206
208
209 append(caughtException);
210 }
211
212
242 IException::IException(const IException &caughtException,
243 ErrorType type, const std::string &message,
244 const char *fileName, int lineNumber) {
245 m_what = NULL;
246 m_message = NULL;
247 m_fileName = NULL;
249
250 m_errorType = type;
251 m_message = new QString(QString(message.c_str()).trimmed());
252 m_fileName = new QString(fileName);
253 m_lineNumber = lineNumber;
254
256
257 append(caughtException);
258 }
259
260
289 IException::IException(const IException &caughtException,
290 ErrorType type, const QString &message,
291 const char *fileName, int lineNumber) {
292 m_what = NULL;
293 m_message = NULL;
294 m_fileName = NULL;
296
297 m_errorType = type;
298 m_message = new QString(message.trimmed());
299 m_fileName = new QString(fileName);
300 m_lineNumber = lineNumber;
301
303
304 append(caughtException);
305 }
306
307
313 IException::IException(const IException &other) : exception(other) {
314 m_what = NULL;
315 m_message = NULL;
316 m_fileName = NULL;
318
319 m_errorType = other.m_errorType;
320 m_lineNumber = other.m_lineNumber;
321
322 if (other.m_what) {
323 int length = strlen(other.m_what);
324 m_what = new char[length + 1];
325 strncpy(m_what, other.m_what, length);
326 m_what[length] = '\0';
327 }
328
329 if (other.m_message) {
330 m_message = new QString(*other.m_message);
331 }
332
333 if (other.m_fileName) {
334 m_fileName = new QString(*other.m_fileName);
335 }
336
337 if (other.m_previousExceptions) {
338 m_previousExceptions = new QList<IException>(*other.m_previousExceptions);
339 }
340 }
341
342
348 delete [] m_what;
349 m_what = NULL;
350
352
353 delete m_message;
354 m_message = NULL;
355
356 delete m_fileName;
357 m_fileName = NULL;
358
359 m_lineNumber = -1;
360
363 }
364
365
373 const char *IException::what() const throw() {
374 return m_what;
375 }
376
407 void IException::append(const IException &exceptionSource) {
409 m_previousExceptions = new QList<IException>;
410 }
411
412 if (exceptionSource.m_previousExceptions) {
413 m_previousExceptions->append(*exceptionSource.m_previousExceptions);
414 }
415
416 m_previousExceptions->append(exceptionSource);
417
418 delete [] m_what;
419 m_what = NULL;
420 m_what = buildWhat();
421 }
422
431
432
443 void IException::print() const {
444 QString errorString = toString();
445 if (errorString != "")
446 cerr << errorString.toLatin1().data() << endl;
447 }
448
449
459 void IException::print(bool printFileInfo) const {
460 QString errorString = toString(printFileInfo);
461 if (errorString != "")
462 cerr << errorString.toLatin1().data() << endl;
463 }
464
465
474 Pvl errors;
475
476 QList<IException> exceptionsToConvert;
477
479 exceptionsToConvert.append(*m_previousExceptions);
480 }
481 exceptionsToConvert.append(*this);
482
483 for (int exceptionIndex = exceptionsToConvert.size() - 1;
484 exceptionIndex >= 0;
485 exceptionIndex--) {
486 const IException &exception(exceptionsToConvert.at(exceptionIndex));
487
488 bool exceptionIsBlank = true;
489 PvlGroup errGroup("Error");
490
491 errGroup += PvlKeyword("Program", Application::Name());
492
493 if (exception.m_errorType != Unknown) {
494 errGroup += PvlKeyword("Class",
495 errorTypeToString(exception.m_errorType));
496 exceptionIsBlank = false;
497 }
498
499 errGroup += PvlKeyword("Code", Isis::toString(exception.m_errorType));
500
501 if (exception.m_message) {
502 exceptionIsBlank = false;
503 QString message(*exception.m_message);
504
505 if (message.size() && message[message.size() - 1] == '.')
506 message = message.mid(0, message.size() - 1);
507 errGroup += PvlKeyword("Message", message);
508 }
509
510 if (exception.m_fileName) {
511 exceptionIsBlank = false;
512 errGroup += PvlKeyword("File", *exception.m_fileName);
513
514 if (exception.m_lineNumber != -1)
515 errGroup += PvlKeyword("Line", Isis::toString(exception.m_lineNumber));
516 }
517
518 if (!exceptionIsBlank)
519 errors.addGroup(errGroup);
520 }
521
522 return errors;
523 }
524
525
535 QString IException::toString() const {
536 bool reportFileLine = true;
537
538 if (Preference::Preferences().hasGroup("ErrorFacility")) {
539 PvlGroup &errorFacility =
540 Preference::Preferences().findGroup("ErrorFacility");
541 if (errorFacility.hasKeyword("FileLine")) {
542 QString fileLine = errorFacility["FileLine"][0];
543 reportFileLine = (fileLine.toUpper() == "ON");
544 }
545 }
546
547 return toString(reportFileLine);
548 }
549
550
562 QString IException::toString(bool includeFileInfo) const {
563 QString result;
564
565 bool usePvlFormat = false;
566
567 if (Preference::Preferences().hasGroup("ErrorFacility")) {
568 PvlGroup &errorFacility =
569 Preference::Preferences().findGroup("ErrorFacility");
570 if (errorFacility.hasKeyword("Format")) {
571 QString format = errorFacility["Format"][0];
572 usePvlFormat = (format.toUpper() == "PVL");
573 }
574 }
575
576 if (usePvlFormat) {
577 Pvl errors = toPvl();
578
579 if (errors.groups() != 0) {
580 stringstream stringStream;
581 stringStream << errors;
582 result = stringStream.str().c_str();
583 }
584 }
585 else {
586 QList<IException> exceptionsToConvert;
587
589 exceptionsToConvert.append(*m_previousExceptions);
590 }
591 exceptionsToConvert.append(*this);
592
593 for (int exceptionIndex = exceptionsToConvert.size() - 1;
594 exceptionIndex >= 0;
595 exceptionIndex--) {
596 const IException &exception(exceptionsToConvert.at(exceptionIndex));
597
598 // Don't put **ERROR** if there is no message or type
599 if (exception.m_errorType != Unknown || exception.m_message) {
600 result += "**" + errorTypeToString(exception.m_errorType) + "**";
601 }
602
603 bool needsPeriod = false;
604 if (exception.m_message) {
605 QString message(*exception.m_message);
606
607 if (message.size() && message[message.size() - 1] == '.')
608 message = message.mid(0, message.size() - 1);
609 // There is always a **TYPE** already in the string, so prefix the
610 // message with a space.
611 result += " " + message;
612 needsPeriod = true;
613 }
614
615 if(includeFileInfo && exception.m_fileName) {
616 result += " in " + *exception.m_fileName;
617 if (exception.m_lineNumber != -1)
618 result += " at " + Isis::toString(exception.m_lineNumber);
619 needsPeriod = true;
620 }
621
622 if (needsPeriod)
623 result += ".";
624
625 if (result.size() && result[result.size() - 1] != '\n')
626 result += "\n";
627 }
628 }
629
630 return result.trimmed();
631 }
632
633
641 std::swap(m_what, other.m_what);
642 std::swap(m_errorType, other.m_errorType);
643 std::swap(m_message, other.m_message);
644 std::swap(m_fileName, other.m_fileName);
645 std::swap(m_lineNumber, other.m_lineNumber);
646 std::swap(m_previousExceptions, other.m_previousExceptions);
647 }
648
649
658 IException copy(rhs);
659 swap(copy);
660
661 return *this;
662 }
663
664
673 QString result;
674
675 switch(type) {
676 case User:
677 result = "USER ERROR";
678 break;
679 case Programmer:
680 result = "PROGRAMMER ERROR";
681 break;
682 case Io:
683 result = "I/O ERROR";
684 break;
685 case Unknown:
686 result = "ERROR";
687 break;
688 }
689
690 return result;
691 }
692
693
702 const QString &string) {
703 ErrorType result = Unknown;
704
705 if(string == "USER ERROR")
706 result = User;
707 else if(string == "PROGRAMMER ERROR")
708 result = Programmer;
709 else if(string == "I/O ERROR")
710 result = Io;
711
712 return result;
713 }
714
715
724 char *IException::buildWhat() const {
725 QString whatStr = toString();
726
727 char *result = new char[whatStr.size() + 1];
728 strncpy(result, whatStr.toLatin1().data(), whatStr.size());
729 result[whatStr.size()] = '\0';
730
731 return result;
732 }
733
734
741 if (m_message->size() == 0) {
742 delete m_message;
743 m_message = NULL;
744 }
745
746 if (m_fileName->size() == 0) {
747 delete m_fileName;
748 m_fileName = NULL;
749 }
750 }
751}
752
static QString Name()
Returns the name of the application.
Isis exception class.
Definition IException.h:91
ErrorType
Contains a set of exception error types.
Definition IException.h:111
@ Unknown
A type of error that cannot be classified as any of the other error types.
Definition IException.h:118
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
Definition IException.h:126
@ Programmer
This error is for when a programmer made an API call that was illegal.
Definition IException.h:146
@ Io
A type of error that occurred when performing an actual I/O operation.
Definition IException.h:155
QString * m_message
The message associated with this exception.
Definition IException.h:225
IException()
The default constructor creates an IException instance with no message, previous exceptions,...
int m_lineNumber
The line in the source code file that threw this exception.
Definition IException.h:235
IException & operator=(const IException &rhs)
Assign the values of rhs to this instance.
static QString errorTypeToString(ErrorType t)
Returns the source of the error in string format for the given ErrorType.
const char * what() const
Returns a string representation of this exception in its current state.
char * m_what
This is used to store the return value of what() in a way that guarantees the returned data will not ...
Definition IException.h:213
ErrorType errorType() const
Returns the source of the error for this exception.
QString toString() const
Returns a string representation of this exception.
QList< IException > * m_previousExceptions
A list of exceptions that caused this exception.
Definition IException.h:240
ErrorType m_errorType
This exception's error source.
Definition IException.h:219
void append(const IException &exceptionSource)
Appends the given exception (and its list of previous exceptions) to this exception's causational exc...
void print() const
Prints a string representation of this exception to stderr.
Pvl toPvl() const
Returns a PVL object representing the contents of this exception.
void swap(IException &other)
Swaps the values of this instance's member data with other.
char * buildWhat() const
Returns a C string containing a string representation of this exception.
~IException()
The destructor frees memory allocated for the message, filename, and list of previous exceptions.
void deleteEmptyMemberStrings()
This is a helper method for the constructors.
static ErrorType stringToErrorType(const QString &s)
Given a string, returns the error type associated with it.
QString * m_fileName
The source code file that threw this exception.
Definition IException.h:230
Contains multiple PvlContainers.
Definition PvlGroup.h:41
Container for cube-like labels.
Definition Pvl.h:119
void append(const QString &file)
Appends PVL information to a file and handles the end of line sequence.
Definition Pvl.cpp:184
A single keyword-value pair.
Definition PvlKeyword.h:87
int groups() const
Returns the number of groups contained.
Definition PvlObject.h:75
void addGroup(const Isis::PvlGroup &group)
Add a group to the object.
Definition PvlObject.h:186
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition IString.cpp:211
Namespace for the standard library.