1 /** 2 * UGENE - Integrated Bioinformatics Tools. 3 * Copyright (C) 2008-2021 UniPro <ugene@unipro.ru> 4 * http://ugene.net 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 2 9 * of the License, or (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 19 * MA 02110-1301, USA. 20 */ 21 22 /** 23 A framework to check, trace and recover from error situation in release mode. 24 The logic is similar to usual assertions in debug mode but in 25 release mode the check is performed and if not passed - the error message 26 is dumped to log. This log can be analyzed and sent as a part of crash handler report 27 28 NOTE: all checks below work in release mode. Be careful not to make code slow! 29 */ 30 #ifndef _U2_SAFE_POINTS_ 31 #define _U2_SAFE_POINTS_ 32 33 #include <assert.h> 34 35 #include <U2Core/Log.h> 36 37 /** 38 Recover utility. Must be used when code tries to recover from invalid internal state 39 by returning from the method some default value. 40 Traces the message to log. Asserts in debug mode. 41 42 Warning: never use this function as a simple check since it stops application execution in debug mode 43 use CHECK_OP instead 44 */ 45 #define SAFE_POINT(condition, message, result) \ 46 if (Q_UNLIKELY(!(condition))) { \ 47 U2::coreLog.error(QString("Trying to recover from error: %1 at %2:%3").arg(message).arg(__FILE__).arg(__LINE__)); \ 48 assert(condition); \ 49 return result; \ 50 } 51 52 /** 53 Recover utility. Must be used when code tries to recover from invalid internal state 54 by returning from the method some default value. 55 Dumps the message to the error-level log. Asserts in debug mode. 56 57 Warning: never use this function as a simple check since it stops application execution in debug mode 58 use CHECK_OP instead 59 60 */ 61 #define SAFE_POINT_OP(os, result) \ 62 if (Q_UNLIKELY(os.hasError())) { \ 63 U2::coreLog.error(QString("Trying to recover from error: %1 at %2:%3").arg(os.getError()).arg(__FILE__).arg(__LINE__)); \ 64 assert(0); \ 65 return result; \ 66 } 67 68 /** 69 Recover utility. Must be used when code tries to recover from invalid internal state 70 by returning from the method some default value. 71 Asserts in debug mode. Performs extra recovery op in release 72 73 Warning: never use this function as a simple check since it stops application execution in debug mode 74 use CHECK_OP instead 75 */ 76 #define SAFE_POINT_EXT(condition, extraOp, result) \ 77 if (Q_UNLIKELY(!(condition))) { \ 78 assert(condition); \ 79 extraOp; \ 80 return result; \ 81 } 82 83 /** 84 FAIL utility. Same as SAFE_POINT but uses unconditional fail. 85 Can be used in code that must be unreachable 86 */ 87 #define FAIL(message, result) \ 88 U2::coreLog.error(QString("Trying to recover from error: %1 at %2:%3").arg(message).arg(__FILE__).arg(__LINE__)); \ 89 assert(0); \ 90 return result; 91 92 /** 93 Checks condition is false and returns the result if it is 94 95 Code style hint: use CHECK macro only to make error processing more compact but not all if {return;} patterns ! 96 */ 97 #define CHECK(condition, result) \ 98 if (!(condition)) { \ 99 return result; \ 100 } 101 102 /** 103 Checks condition is false and performs a sequence of operations if it is. 104 105 Code style hint: use CHECK macro only to make error processing more compact but not all if {operation1; operation2;} patterns ! 106 */ 107 #define CHECK_OPERATIONS(condition, extraOp1, extraOp2) \ 108 if (!(condition)) { \ 109 extraOp1; \ 110 extraOp2; \ 111 } 112 113 /** 114 Checks condition is false and performs an operation if it is. 115 116 Code style hint: use CHECK macro only to make error processing more compact but not all if {operation;} patterns ! 117 */ 118 #define CHECK_OPERATION(condition, extraOp) CHECK_OPERATIONS(condition, extraOp, ) 119 120 /** 121 Checks condition is false and breaks if it is. 122 123 Code style hint: use CHECK macro only to make error processing more compact but not all if {break;} patterns ! 124 */ 125 #define CHECK_BREAK(condition) CHECK_OPERATION(condition, break) 126 127 /** 128 Checks condition is false and continue the cycle if it is. 129 */ 130 #define CHECK_CONTINUE(condition) CHECK_OPERATION(condition, continue) 131 132 /** 133 Checks condition is false and breaks if it is. 134 Before breaking the 'extraOp' operation is performed (for example logging) 135 136 Code style hint: use CHECK macro only to make error processing more compact but not all if {operation; break;} patterns ! 137 */ 138 #define CHECK_EXT_BREAK(condition, extraOp) CHECK_OPERATIONS(condition, extraOp, break) 139 140 /** 141 Checks condition is false and returns the result if it is. 142 Before the result is returned the 'extraOp' operation is performed (for example logging) 143 144 Code style hint: use CHECK macro only to make error processing more compact but not all if {return;} patterns ! 145 */ 146 #define CHECK_EXT(condition, extraOp, result) \ 147 if (!(condition)) { \ 148 extraOp; \ 149 return result; \ 150 } 151 152 /** 153 Checks that operation is neither not failed nor canceled and returns the result if it does 154 */ 155 #define CHECK_OP(os, result) CHECK(!os.isCoR(), result) 156 157 /** 158 Checks that operation is neither not failed nor canceled and breaks if it does 159 */ 160 #define CHECK_OP_BREAK(os) CHECK_BREAK(!os.isCoR()) 161 162 /** 163 Checks that operation is neither failed nor canceled and returns the result if it does. 164 Before the result is returned the 'extraOp' operation is performed (for example logging) 165 */ 166 #define CHECK_OP_EXT(os, extraOp, result) CHECK_EXT(!(os.isCoR()), extraOp, result) 167 168 #endif 169