Simbody 3.7
Exception.h
Go to the documentation of this file.
1#ifndef SimTK_SimTKCOMMON_EXCEPTION_H_
2#define SimTK_SimTKCOMMON_EXCEPTION_H_
3
4/* -------------------------------------------------------------------------- *
5 * Simbody(tm): SimTKcommon *
6 * -------------------------------------------------------------------------- *
7 * This is part of the SimTK biosimulation toolkit originating from *
8 * Simbios, the NIH National Center for Physics-Based Simulation of *
9 * Biological Structures at Stanford, funded under the NIH Roadmap for *
10 * Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody. *
11 * *
12 * Portions copyright (c) 2005-15 Stanford University and the Authors. *
13 * Authors: Michael Sherman *
14 * Contributors: *
15 * *
16 * Licensed under the Apache License, Version 2.0 (the "License"); you may *
17 * not use this file except in compliance with the License. You may obtain a *
18 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. *
19 * *
20 * Unless required by applicable law or agreed to in writing, software *
21 * distributed under the License is distributed on an "AS IS" BASIS, *
22 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
23 * See the License for the specific language governing permissions and *
24 * limitations under the License. *
25 * -------------------------------------------------------------------------- */
26
28
29#include <string>
30#include <iostream>
31#include <exception>
32#include <cstdarg>
33#include <cstdio>
34
35namespace SimTK {
36
37namespace Exception {
38
39 // Keeps MS VC++ quiet about sprintf, strcpy, etc.
40#ifdef _MSC_VER
41#pragma warning(push)
42#pragma warning(disable:4996)
43#endif
44
45// SimTK::Exception::Base
46class Base : public std::exception {
47public:
48 explicit Base(const char* fn="<UNKNOWN>", int ln=0)
49 : fileName(fn), lineNo(ln) { }
50 virtual ~Base() throw() { }
51 const std::string& getMessage() const { return msg; }
52 const std::string& getMessageText() const { return text; }
53
54 // override virtual function from std::exception
55 const char* what() const throw() override {return getMessage().c_str();}
56protected:
57 void setMessage(const std::string& msgin) {
58 text = msgin;
59 msg = "SimTK Exception thrown at " + where() + ":\n " + msgin;
60 }
61private:
62 std::string fileName; // where the exception was thrown
63 int lineNo;
64 std::string msg; // a message formatted for display by catcher
65 std::string text; // the original passed-in text
66
67 static std::string shortenFileName(const std::string& fn)
68 { std::string::size_type pos = fn.find_last_of("/\\");
69 if (pos+1>=fn.size()) pos=0;
70 return std::string(fn,(int)(pos+1),(int)(fn.size()-(pos+1)));
71 }
72
73 std::string where() const {
74 char buf[32];
75 sprintf(buf,"%d",lineNo);
76 return shortenFileName(fileName) + ":" + std::string(buf);
77 }
78};
79
86class Assert : public Base {
87public:
88 Assert(const char* fn, int ln, const char* assertion,
89 const char* fmt ...) : Base(fn,ln)
90 {
91 char buf[1024];
92 va_list args;
93 va_start(args, fmt);
94 vsprintf(buf, fmt, args);
95
96 setMessage("Internal bug detected: " + std::string(buf)
97 + "\n (Assertion '" + std::string(assertion) + "' failed).\n"
98 " Please file an Issue at https://github.com/simbody/simbody/issues.\n"
99 " Include the above information and anything else needed to reproduce the problem.");
100 va_end(args);
101 }
102 virtual ~Assert() throw() { }
103};
104
113class ErrorCheck : public Base {
114public:
115 ErrorCheck(const char* fn, int ln, const char* assertion,
116 const char* whereChecked, // e.g., ClassName::methodName()
117 const char* fmt ...) : Base(fn,ln)
118 {
119 char buf[1024];
120 va_list args;
121 va_start(args, fmt);
122 vsprintf(buf, fmt, args);
123
124 setMessage("Error detected by Simbody method "
125 + std::string(whereChecked) + ": "
126 + std::string(buf)
127 + "\n (Required condition '" + std::string(assertion) + "' was not met.)\n");
128 va_end(args);
129 }
130 virtual ~ErrorCheck() throw() { }
131};
132
140class APIArgcheckFailed : public Base {
141public:
142 APIArgcheckFailed(const char* fn, int ln, const char* assertion,
143 const char* className, const char* methodName,
144 const char* fmt ...) : Base(fn,ln)
145 {
146 char buf[1024];
147 va_list args;
148 va_start(args, fmt);
149 vsprintf(buf, fmt, args);
150 setMessage("Bad call to Simbody API method "
151 + std::string(className) + "::" + std::string(methodName) + "(): "
152 + std::string(buf)
153 + "\n (Required condition '" + std::string(assertion) + "' was not met.)");
154 va_end(args);
155 }
156 virtual ~APIArgcheckFailed() throw() { }
157};
158
159
160class IndexOutOfRange : public Base {
161public:
162 IndexOutOfRange(const char* fn, int ln, const char* indexName,
163 long long lb, long long index, long long ub, const char* where)
164 : Base(fn,ln)
165 {
166 char buf[1024];
167
168 sprintf(buf, "Index out of range in %s: expected %lld <= %s < %lld but %s=%lld.",
169 where,lb,indexName,ub,indexName,index);
170 setMessage(std::string(buf));
171 }
172 virtual ~IndexOutOfRange() throw() { }
173};
174
175class SizeOutOfRange : public Base {
176public:
177 SizeOutOfRange(const char* fn, int ln, const char* szName,
178 unsigned long long sz, unsigned long long maxsz, const char* where)
179 : Base(fn,ln)
180 {
181 char buf[1024];
182
183 sprintf(buf, "Size out of range in %s: expected 0 <= %s <= %llu but %s=%llu.",
184 where,szName,maxsz,szName,sz);
185 setMessage(std::string(buf));
186 }
187 virtual ~SizeOutOfRange() throw() { }
188};
189
190class SizeWasNegative : public Base {
191public:
192 SizeWasNegative(const char* fn, int ln, const char* szName,
193 unsigned long long sz, const char* where)
194 : Base(fn,ln)
195 {
196 char buf[1024];
197
198 sprintf(buf, "Size argument was negative in %s: expected 0 <= %s but %s=%llu.",
199 where,szName,szName,sz);
200 setMessage(std::string(buf));
201 }
202 virtual ~SizeWasNegative() throw() { }
203};
204
205class ValueOutOfRange : public Base {
206public:
207 ValueOutOfRange(const char* fn, int ln, const char* valueName,
208 double lowerBound, double value, double upperBound,
209 const char* where)
210 : Base(fn,ln)
211 {
212 char buf[1024];
213
214 sprintf(buf, "Value out of range in %s: expected %g <= %s <= %g but %s=%g.",
215 where,lowerBound,valueName,upperBound,valueName,value);
216 setMessage(std::string(buf));
217 }
218 virtual ~ValueOutOfRange() throw() { }
219};
220
221class ValueWasNegative : public Base {
222public:
223 ValueWasNegative(const char* fn, int ln, const char* valueName,
224 double value, const char* where)
225 : Base(fn,ln)
226 {
227 char buf[1024];
228
229 sprintf(buf, "Expected non-negative value for %s in %s but got %g.",
230 valueName,where,value);
231 setMessage(std::string(buf));
232 }
233 virtual ~ValueWasNegative() throw() { }
234};
235
236class UnimplementedMethod : public Base {
237public:
238 UnimplementedMethod(const char* fn, int ln, std::string methodName)
239 : Base(fn,ln)
240 {
241 setMessage("The method " + methodName
242 + "is not yet implemented. Please post to the Simbody forum"
243 " to find a workaround or request implementation.");
244 }
245 virtual ~UnimplementedMethod() throw() { }
246};
247
249public:
250 UnimplementedVirtualMethod(const char* fn, int ln,
251 std::string baseClass, std::string methodName)
252 : Base(fn,ln)
253 {
254 setMessage("The base class " + baseClass +
255 " dummy implementation of method " + methodName
256 + "() was invoked because a derived class did not provide an implementation.");
257 }
258 virtual ~UnimplementedVirtualMethod() throw() { }
259};
260
261class IncompatibleValues : public Base {
262public:
263 IncompatibleValues(const char* fn, int ln, std::string src, std::string dest) : Base(fn,ln)
264 {
265 setMessage("Attempt to assign a Value<"+src+"> to a Value<"+dest+">");
266 }
267 virtual ~IncompatibleValues() throw() { }
268};
269
271public:
272 OperationNotAllowedOnView(const char* fn, int ln, const std::string& op) : Base(fn,ln)
273 {
274 setMessage("Operation '" + op + "' allowed only for owners, not views");
275 }
276 virtual ~OperationNotAllowedOnView() throw() { }
277};
278
280public:
281 OperationNotAllowedOnOwner(const char* fn, int ln, const std::string& op) : Base(fn,ln)
282 {
283 setMessage("Operation '" + op + "' allowed only for views, not owners");
284 }
285 virtual ~OperationNotAllowedOnOwner() throw() { }
286};
287
289public:
290 OperationNotAllowedOnNonconstReadOnlyView(const char* fn, int ln, const std::string& op) : Base(fn,ln)
291 {
292 setMessage("Operation '" + op + "' not allowed on non-const readonly view");
293 }
295};
296
297// SimTK::Exception::Cant
298class Cant : public Base {
299public:
300 Cant(const char* fn, int ln, const std::string& s) : Base(fn,ln)
301 {
302 setMessage("Can't perform operation: " + s);
303 }
304 virtual ~Cant() throw() { }
305};
306
307#ifdef _MSC_VER
308#pragma warning(pop)
309#endif
310
311} // namespace Exception
312} // namespace SimTK
313
314#define SimTK_THROW(exc) \
315 throw exc(__FILE__, __LINE__)
316#define SimTK_THROW1(exc,a1) \
317 throw exc(__FILE__, __LINE__,a1)
318#define SimTK_THROW2(exc,a1,a2) \
319 throw exc(__FILE__, __LINE__,a1,a2)
320#define SimTK_THROW3(exc,a1,a2,a3) \
321 throw exc(__FILE__, __LINE__,a1,a2,a3)
322#define SimTK_THROW4(exc,a1,a2,a3,a4) \
323 throw exc(__FILE__, __LINE__,a1,a2,a3,a4)
324#define SimTK_THROW5(exc,a1,a2,a3,a4,a5) \
325 throw exc(__FILE__, __LINE__,a1,a2,a3,a4,a5)
326#define SimTK_THROW6(exc,a1,a2,a3,a4,a5,a6) \
327 throw exc(__FILE__, __LINE__,a1,a2,a3,a4,a5,a6)
328#define SimTK_THROW7(exc,a1,a2,a3,a4,a5,a6,a7) \
329 throw exc(__FILE__, __LINE__,a1,a2,a3,a4,a5,a6,a7)
330#define SimTK_THROW8(exc,a1,a2,a3,a4,a5,a6,a7,a8) \
331 throw exc(__FILE__, __LINE__,a1,a2,a3,a4,a5,a6,a7,a8)
332#define SimTK_THROW9(exc,a1,a2,a3,a4,a5,a6,a7,a8,a9) \
333 throw exc(__FILE__, __LINE__,a1,a2,a3,a4,a5,a6,a7,a8,a9)
334#define SimTK_THROW10(exc,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) \
335 throw exc(__FILE__, __LINE__,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
336
337#endif // SimTK_SimTKCOMMON_EXCEPTION_H_
338
Mandatory first inclusion for any Simbody source or header file.
This is for reporting problems detected by checking the caller's supplied arguments to a SimTK API me...
Definition: Exception.h:140
APIArgcheckFailed(const char *fn, int ln, const char *assertion, const char *className, const char *methodName, const char *fmt ...)
Definition: Exception.h:142
virtual ~APIArgcheckFailed()
Definition: Exception.h:156
This is for reporting internally-detected bugs only, not problems induced by confused users (that is,...
Definition: Exception.h:86
virtual ~Assert()
Definition: Exception.h:102
Assert(const char *fn, int ln, const char *assertion, const char *fmt ...)
Definition: Exception.h:88
Definition: Exception.h:46
const char * what() const override
Definition: Exception.h:55
virtual ~Base()
Definition: Exception.h:50
Base(const char *fn="<UNKNOWN>", int ln=0)
Definition: Exception.h:48
const std::string & getMessageText() const
Definition: Exception.h:52
void setMessage(const std::string &msgin)
Definition: Exception.h:57
const std::string & getMessage() const
Definition: Exception.h:51
Definition: Exception.h:298
Cant(const char *fn, int ln, const std::string &s)
Definition: Exception.h:300
virtual ~Cant()
Definition: Exception.h:304
This is for reporting errors occurring during execution of SimTK core methods, beyond those caused by...
Definition: Exception.h:113
ErrorCheck(const char *fn, int ln, const char *assertion, const char *whereChecked, const char *fmt ...)
Definition: Exception.h:115
virtual ~ErrorCheck()
Definition: Exception.h:130
Definition: Exception.h:261
IncompatibleValues(const char *fn, int ln, std::string src, std::string dest)
Definition: Exception.h:263
virtual ~IncompatibleValues()
Definition: Exception.h:267
Definition: Exception.h:160
virtual ~IndexOutOfRange()
Definition: Exception.h:172
IndexOutOfRange(const char *fn, int ln, const char *indexName, long long lb, long long index, long long ub, const char *where)
Definition: Exception.h:162
virtual ~OperationNotAllowedOnNonconstReadOnlyView()
Definition: Exception.h:294
OperationNotAllowedOnNonconstReadOnlyView(const char *fn, int ln, const std::string &op)
Definition: Exception.h:290
virtual ~OperationNotAllowedOnOwner()
Definition: Exception.h:285
OperationNotAllowedOnOwner(const char *fn, int ln, const std::string &op)
Definition: Exception.h:281
OperationNotAllowedOnView(const char *fn, int ln, const std::string &op)
Definition: Exception.h:272
virtual ~OperationNotAllowedOnView()
Definition: Exception.h:276
Definition: Exception.h:175
SizeOutOfRange(const char *fn, int ln, const char *szName, unsigned long long sz, unsigned long long maxsz, const char *where)
Definition: Exception.h:177
virtual ~SizeOutOfRange()
Definition: Exception.h:187
Definition: Exception.h:190
virtual ~SizeWasNegative()
Definition: Exception.h:202
SizeWasNegative(const char *fn, int ln, const char *szName, unsigned long long sz, const char *where)
Definition: Exception.h:192
Definition: Exception.h:236
UnimplementedMethod(const char *fn, int ln, std::string methodName)
Definition: Exception.h:238
virtual ~UnimplementedMethod()
Definition: Exception.h:245
UnimplementedVirtualMethod(const char *fn, int ln, std::string baseClass, std::string methodName)
Definition: Exception.h:250
virtual ~UnimplementedVirtualMethod()
Definition: Exception.h:258
Definition: Exception.h:205
virtual ~ValueOutOfRange()
Definition: Exception.h:218
ValueOutOfRange(const char *fn, int ln, const char *valueName, double lowerBound, double value, double upperBound, const char *where)
Definition: Exception.h:207
Definition: Exception.h:221
ValueWasNegative(const char *fn, int ln, const char *valueName, double value, const char *where)
Definition: Exception.h:223
virtual ~ValueWasNegative()
Definition: Exception.h:233
This is the top-level SimTK namespace into which all SimTK names are placed to avoid collision with o...
Definition: Assembler.h:37