Simbody  3.8
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 
35 namespace SimTK {
36 
37 namespace 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
46 class Base : public std::exception {
47 public:
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();}
56 protected:
57  void setMessage(const std::string& msgin) {
58  text = msgin;
59  msg = "SimTK Exception thrown at " + where() + ":\n " + msgin;
60  }
61 private:
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  const int n = 32;
75  char buf[n];
76  snprintf(buf,n,"%d",lineNo);
77  return shortenFileName(fileName) + ":" + std::string(buf);
78  }
79 };
80 
87 class Assert : public Base {
88 public:
89  Assert(const char* fn, int ln, const char* assertion,
90  const char* fmt ...) : Base(fn,ln)
91  {
92  const int n = 1024;
93  char buf[n];
94  va_list args;
95  va_start(args, fmt);
96  vsnprintf(buf, n, fmt, args);
97 
98  setMessage("Internal bug detected: " + std::string(buf)
99  + "\n (Assertion '" + std::string(assertion) + "' failed).\n"
100  " Please file an Issue at https://github.com/simbody/simbody/issues.\n"
101  " Include the above information and anything else needed to reproduce the problem.");
102  va_end(args);
103  }
104  virtual ~Assert() throw() { }
105 };
106 
115 class ErrorCheck : public Base {
116 public:
117  ErrorCheck(const char* fn, int ln, const char* assertion,
118  const char* whereChecked, // e.g., ClassName::methodName()
119  const char* fmt ...) : Base(fn,ln)
120  {
121  const int n = 1024;
122  char buf[n];
123  va_list args;
124  va_start(args, fmt);
125  vsnprintf(buf, n, fmt, args);
126 
127  setMessage("Error detected by Simbody method "
128  + std::string(whereChecked) + ": "
129  + std::string(buf)
130  + "\n (Required condition '" + std::string(assertion) + "' was not met.)\n");
131  va_end(args);
132  }
133  virtual ~ErrorCheck() throw() { }
134 };
135 
143 class APIArgcheckFailed : public Base {
144 public:
145  APIArgcheckFailed(const char* fn, int ln, const char* assertion,
146  const char* className, const char* methodName,
147  const char* fmt ...) : Base(fn,ln)
148  {
149  const int n = 1024;
150  char buf[n];
151  va_list args;
152  va_start(args, fmt);
153  vsnprintf(buf, n, fmt, args);
154  setMessage("Bad call to Simbody API method "
155  + std::string(className) + "::" + std::string(methodName) + "(): "
156  + std::string(buf)
157  + "\n (Required condition '" + std::string(assertion) + "' was not met.)");
158  va_end(args);
159  }
160  virtual ~APIArgcheckFailed() throw() { }
161 };
162 
163 
164 class IndexOutOfRange : public Base {
165 public:
166  IndexOutOfRange(const char* fn, int ln, const char* indexName,
167  long long lb, long long index, long long ub, const char* where)
168  : Base(fn,ln)
169  {
170  const int n = 1024;
171  char buf[n];
172 
173  snprintf(buf, n, "Index out of range in %s: expected %lld <= %s < %lld but %s=%lld.",
174  where,lb,indexName,ub,indexName,index);
175  setMessage(std::string(buf));
176  }
177  virtual ~IndexOutOfRange() throw() { }
178 };
179 
180 class SizeOutOfRange : public Base {
181 public:
182  SizeOutOfRange(const char* fn, int ln, const char* szName,
183  unsigned long long sz, unsigned long long maxsz, const char* where)
184  : Base(fn,ln)
185  {
186  const int n = 1024;
187  char buf[n];
188 
189  snprintf(buf, n, "Size out of range in %s: expected 0 <= %s <= %llu but %s=%llu.",
190  where,szName,maxsz,szName,sz);
191  setMessage(std::string(buf));
192  }
193  virtual ~SizeOutOfRange() throw() { }
194 };
195 
196 class SizeWasNegative : public Base {
197 public:
198  SizeWasNegative(const char* fn, int ln, const char* szName,
199  unsigned long long sz, const char* where)
200  : Base(fn,ln)
201  {
202  const int n = 1024;
203  char buf[n];
204 
205  snprintf(buf, n, "Size argument was negative in %s: expected 0 <= %s but %s=%llu.",
206  where,szName,szName,sz);
207  setMessage(std::string(buf));
208  }
209  virtual ~SizeWasNegative() throw() { }
210 };
211 
212 class ValueOutOfRange : public Base {
213 public:
214  ValueOutOfRange(const char* fn, int ln, const char* valueName,
215  double lowerBound, double value, double upperBound,
216  const char* where)
217  : Base(fn,ln)
218  {
219  const int n = 1024;
220  char buf[n];
221 
222  snprintf(buf, n, "Value out of range in %s: expected %g <= %s <= %g but %s=%g.",
223  where,lowerBound,valueName,upperBound,valueName,value);
224  setMessage(std::string(buf));
225  }
226  virtual ~ValueOutOfRange() throw() { }
227 };
228 
229 class ValueWasNegative : public Base {
230 public:
231  ValueWasNegative(const char* fn, int ln, const char* valueName,
232  double value, const char* where)
233  : Base(fn,ln)
234  {
235  const int n = 1024;
236  char buf[n];
237 
238  snprintf(buf, n, "Expected non-negative value for %s in %s but got %g.",
239  valueName,where,value);
240  setMessage(std::string(buf));
241  }
242  virtual ~ValueWasNegative() throw() { }
243 };
244 
245 class UnimplementedMethod : public Base {
246 public:
247  UnimplementedMethod(const char* fn, int ln, std::string methodName)
248  : Base(fn,ln)
249  {
250  setMessage("The method " + methodName
251  + "is not yet implemented. Please post to the Simbody forum"
252  " to find a workaround or request implementation.");
253  }
254  virtual ~UnimplementedMethod() throw() { }
255 };
256 
258 public:
259  UnimplementedVirtualMethod(const char* fn, int ln,
260  std::string baseClass, std::string methodName)
261  : Base(fn,ln)
262  {
263  setMessage("The base class " + baseClass +
264  " dummy implementation of method " + methodName
265  + "() was invoked because a derived class did not provide an implementation.");
266  }
267  virtual ~UnimplementedVirtualMethod() throw() { }
268 };
269 
270 class IncompatibleValues : public Base {
271 public:
272  IncompatibleValues(const char* fn, int ln, std::string src, std::string dest) : Base(fn,ln)
273  {
274  setMessage("Attempt to assign a Value<"+src+"> to a Value<"+dest+">");
275  }
276  virtual ~IncompatibleValues() throw() { }
277 };
278 
280 public:
281  OperationNotAllowedOnView(const char* fn, int ln, const std::string& op) : Base(fn,ln)
282  {
283  setMessage("Operation '" + op + "' allowed only for owners, not views");
284  }
285  virtual ~OperationNotAllowedOnView() throw() { }
286 };
287 
289 public:
290  OperationNotAllowedOnOwner(const char* fn, int ln, const std::string& op) : Base(fn,ln)
291  {
292  setMessage("Operation '" + op + "' allowed only for views, not owners");
293  }
294  virtual ~OperationNotAllowedOnOwner() throw() { }
295 };
296 
298 public:
299  OperationNotAllowedOnNonconstReadOnlyView(const char* fn, int ln, const std::string& op) : Base(fn,ln)
300  {
301  setMessage("Operation '" + op + "' not allowed on non-const readonly view");
302  }
304 };
305 
306 // SimTK::Exception::Cant
307 class Cant : public Base {
308 public:
309  Cant(const char* fn, int ln, const std::string& s) : Base(fn,ln)
310  {
311  setMessage("Can't perform operation: " + s);
312  }
313  virtual ~Cant() throw() { }
314 };
315 
316 #ifdef _MSC_VER
317 #pragma warning(pop)
318 #endif
319 
320 } // namespace Exception
321 } // namespace SimTK
322 
323 #define SimTK_THROW(exc) \
324  throw exc(__FILE__, __LINE__)
325 #define SimTK_THROW1(exc,a1) \
326  throw exc(__FILE__, __LINE__,a1)
327 #define SimTK_THROW2(exc,a1,a2) \
328  throw exc(__FILE__, __LINE__,a1,a2)
329 #define SimTK_THROW3(exc,a1,a2,a3) \
330  throw exc(__FILE__, __LINE__,a1,a2,a3)
331 #define SimTK_THROW4(exc,a1,a2,a3,a4) \
332  throw exc(__FILE__, __LINE__,a1,a2,a3,a4)
333 #define SimTK_THROW5(exc,a1,a2,a3,a4,a5) \
334  throw exc(__FILE__, __LINE__,a1,a2,a3,a4,a5)
335 #define SimTK_THROW6(exc,a1,a2,a3,a4,a5,a6) \
336  throw exc(__FILE__, __LINE__,a1,a2,a3,a4,a5,a6)
337 #define SimTK_THROW7(exc,a1,a2,a3,a4,a5,a6,a7) \
338  throw exc(__FILE__, __LINE__,a1,a2,a3,a4,a5,a6,a7)
339 #define SimTK_THROW8(exc,a1,a2,a3,a4,a5,a6,a7,a8) \
340  throw exc(__FILE__, __LINE__,a1,a2,a3,a4,a5,a6,a7,a8)
341 #define SimTK_THROW9(exc,a1,a2,a3,a4,a5,a6,a7,a8,a9) \
342  throw exc(__FILE__, __LINE__,a1,a2,a3,a4,a5,a6,a7,a8,a9)
343 #define SimTK_THROW10(exc,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) \
344  throw exc(__FILE__, __LINE__,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
345 
346 #endif // SimTK_SimTKCOMMON_EXCEPTION_H_
347 
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:143
APIArgcheckFailed(const char *fn, int ln, const char *assertion, const char *className, const char *methodName, const char *fmt ...)
Definition: Exception.h:145
virtual ~APIArgcheckFailed()
Definition: Exception.h:160
This is for reporting internally-detected bugs only, not problems induced by confused users (that is,...
Definition: Exception.h:87
virtual ~Assert()
Definition: Exception.h:104
Assert(const char *fn, int ln, const char *assertion, const char *fmt ...)
Definition: Exception.h:89
Definition: Exception.h:46
virtual ~Base()
Definition: Exception.h:50
const std::string & getMessage() const
Definition: Exception.h:51
Base(const char *fn="<UNKNOWN>", int ln=0)
Definition: Exception.h:48
const std::string & getMessageText() const
Definition: Exception.h:52
const char * what() const override
Definition: Exception.h:55
void setMessage(const std::string &msgin)
Definition: Exception.h:57
Definition: Exception.h:307
Cant(const char *fn, int ln, const std::string &s)
Definition: Exception.h:309
virtual ~Cant()
Definition: Exception.h:313
This is for reporting errors occurring during execution of SimTK core methods, beyond those caused by...
Definition: Exception.h:115
ErrorCheck(const char *fn, int ln, const char *assertion, const char *whereChecked, const char *fmt ...)
Definition: Exception.h:117
virtual ~ErrorCheck()
Definition: Exception.h:133
Definition: Exception.h:270
IncompatibleValues(const char *fn, int ln, std::string src, std::string dest)
Definition: Exception.h:272
virtual ~IncompatibleValues()
Definition: Exception.h:276
Definition: Exception.h:164
virtual ~IndexOutOfRange()
Definition: Exception.h:177
IndexOutOfRange(const char *fn, int ln, const char *indexName, long long lb, long long index, long long ub, const char *where)
Definition: Exception.h:166
virtual ~OperationNotAllowedOnNonconstReadOnlyView()
Definition: Exception.h:303
OperationNotAllowedOnNonconstReadOnlyView(const char *fn, int ln, const std::string &op)
Definition: Exception.h:299
virtual ~OperationNotAllowedOnOwner()
Definition: Exception.h:294
OperationNotAllowedOnOwner(const char *fn, int ln, const std::string &op)
Definition: Exception.h:290
OperationNotAllowedOnView(const char *fn, int ln, const std::string &op)
Definition: Exception.h:281
virtual ~OperationNotAllowedOnView()
Definition: Exception.h:285
Definition: Exception.h:180
SizeOutOfRange(const char *fn, int ln, const char *szName, unsigned long long sz, unsigned long long maxsz, const char *where)
Definition: Exception.h:182
virtual ~SizeOutOfRange()
Definition: Exception.h:193
Definition: Exception.h:196
virtual ~SizeWasNegative()
Definition: Exception.h:209
SizeWasNegative(const char *fn, int ln, const char *szName, unsigned long long sz, const char *where)
Definition: Exception.h:198
Definition: Exception.h:245
UnimplementedMethod(const char *fn, int ln, std::string methodName)
Definition: Exception.h:247
virtual ~UnimplementedMethod()
Definition: Exception.h:254
UnimplementedVirtualMethod(const char *fn, int ln, std::string baseClass, std::string methodName)
Definition: Exception.h:259
virtual ~UnimplementedVirtualMethod()
Definition: Exception.h:267
Definition: Exception.h:212
virtual ~ValueOutOfRange()
Definition: Exception.h:226
ValueOutOfRange(const char *fn, int ln, const char *valueName, double lowerBound, double value, double upperBound, const char *where)
Definition: Exception.h:214
Definition: Exception.h:229
ValueWasNegative(const char *fn, int ln, const char *valueName, double value, const char *where)
Definition: Exception.h:231
virtual ~ValueWasNegative()
Definition: Exception.h:242
This is the top-level SimTK namespace into which all SimTK names are placed to avoid collision with o...
Definition: Assembler.h:37