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 
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  char buf[32];
75  sprintf(buf,"%d",lineNo);
76  return shortenFileName(fileName) + ":" + std::string(buf);
77  }
78 };
79 
86 class Assert : public Base {
87 public:
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 
113 class ErrorCheck : public Base {
114 public:
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 
140 class APIArgcheckFailed : public Base {
141 public:
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 
160 class IndexOutOfRange : public Base {
161 public:
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 
175 class SizeOutOfRange : public Base {
176 public:
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 
190 class SizeWasNegative : public Base {
191 public:
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 
205 class ValueOutOfRange : public Base {
206 public:
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 
221 class ValueWasNegative : public Base {
222 public:
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 
236 class UnimplementedMethod : public Base {
237 public:
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 
249 public:
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 
261 class IncompatibleValues : public Base {
262 public:
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 
271 public:
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 
280 public:
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 
289 public:
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
298 class Cant : public Base {
299 public:
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 
virtual ~UnimplementedMethod()
Definition: Exception.h:245
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:205
virtual ~Assert()
Definition: Exception.h:102
const char * what() const override
Definition: Exception.h:55
SizeOutOfRange(const char *fn, int ln, const char *szName, unsigned long long sz, unsigned long long maxsz, const char *where)
Definition: Exception.h:177
Base(const char *fn="<UNKNOWN>", int ln=0)
Definition: Exception.h:48
virtual ~Base()
Definition: Exception.h:50
void setMessage(const std::string &msgin)
Definition: Exception.h:57
This is the top-level SimTK namespace into which all SimTK names are placed to avoid collision with o...
Definition: Assembler.h:37
const std::string & getMessageText() const
Definition: Exception.h:52
This is for reporting internally-detected bugs only, not problems induced by confused users (that is...
Definition: Exception.h:86
virtual ~IndexOutOfRange()
Definition: Exception.h:172
ErrorCheck(const char *fn, int ln, const char *assertion, const char *whereChecked, const char *fmt ...)
Definition: Exception.h:115
OperationNotAllowedOnNonconstReadOnlyView(const char *fn, int ln, const std::string &op)
Definition: Exception.h:290
SizeWasNegative(const char *fn, int ln, const char *szName, unsigned long long sz, const char *where)
Definition: Exception.h:192
Definition: Exception.h:298
virtual ~ErrorCheck()
Definition: Exception.h:130
const std::string & getMessage() const
Definition: Exception.h:51
Definition: Exception.h:175
Definition: Exception.h:190
UnimplementedMethod(const char *fn, int ln, std::string methodName)
Definition: Exception.h:238
virtual ~OperationNotAllowedOnView()
Definition: Exception.h:276
virtual ~SizeWasNegative()
Definition: Exception.h:202
virtual ~SizeOutOfRange()
Definition: Exception.h:187
This is for reporting errors occurring during execution of SimTK core methods, beyond those caused by...
Definition: Exception.h:113
APIArgcheckFailed(const char *fn, int ln, const char *assertion, const char *className, const char *methodName, const char *fmt ...)
Definition: Exception.h:142
virtual ~Cant()
Definition: Exception.h:304
Definition: Exception.h:46
Definition: Exception.h:160
Definition: Exception.h:261
UnimplementedVirtualMethod(const char *fn, int ln, std::string baseClass, std::string methodName)
Definition: Exception.h:250
virtual ~UnimplementedVirtualMethod()
Definition: Exception.h:258
Assert(const char *fn, int ln, const char *assertion, const char *fmt ...)
Definition: Exception.h:88
virtual ~OperationNotAllowedOnNonconstReadOnlyView()
Definition: Exception.h:294
IncompatibleValues(const char *fn, int ln, std::string src, std::string dest)
Definition: Exception.h:263
virtual ~APIArgcheckFailed()
Definition: Exception.h:156
Definition: Exception.h:221
This is for reporting problems detected by checking the caller&#39;s supplied arguments to a SimTK API me...
Definition: Exception.h:140
OperationNotAllowedOnOwner(const char *fn, int ln, const std::string &op)
Definition: Exception.h:281
ValueWasNegative(const char *fn, int ln, const char *valueName, double value, const char *where)
Definition: Exception.h:223
virtual ~ValueOutOfRange()
Definition: Exception.h:218
Mandatory first inclusion for any Simbody source or header file.
Definition: Exception.h:236
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
Cant(const char *fn, int ln, const std::string &s)
Definition: Exception.h:300
virtual ~IncompatibleValues()
Definition: Exception.h:267
virtual ~OperationNotAllowedOnOwner()
Definition: Exception.h:285
OperationNotAllowedOnView(const char *fn, int ln, const std::string &op)
Definition: Exception.h:272
virtual ~ValueWasNegative()
Definition: Exception.h:233