The following code terminates abnormally as no object is explicitly thrown. What is thrown by throw statement in the following code?
int main()
{
try{
cout<<"try";
throw ;
}
catch(...){
cout<<"catch";
}
return 0;
}
throw without an argument should only be used inside a catch statement, to rethrow the caught exception object. You code tries to use it outside the catch statement - instead you should pick a type to throw, if in doubt it's not unreasonable to start with std::runtime_error. For more options, see here. You can also throw your own types, but it's usually a good idea to derive them from one of the Standard-library provided types so client code has a better chance at specifying appropriate handling for all logically similar errors, rather than having to catch and handle them separately and being constantly updated for each new possible error.
FWIW, the Standard says in 15.1/9:
If no exception is presently being handled, executing a throw-expression with no operand calls std::terminate().
So very explicitly, the answer to "What is thrown..." is that no throwing is done, and std::terminate is called instead.
So the question is: "What happens when I throw outside a catch block?" The answer to this can be found in its documentation:
Rethrows the currently handled exception. Abandons the execution of the current catch block and passes control to the next matching exception handler (but not to another catch clause after the same try block: its compound-statement is considered to have been 'exited'), reusing the existing exception object: no new objects are made. This form is only allowed when an exception is presently being handled (it calls std::terminate if used otherwise). The catch clause associated with a function-try-block must exit via rethrowing if used on a constructor.
Emphasize mine.
Related
The python Exception class is supposed to be used for all user defined exceptions. Documentation also says it is used by all non-system-exiting builtin exceptions. I need to create a user defined exception that will system exit if not handled. In quick tests, calling a method (while not using try...catch) that raises my user defined exception doesn't cause an exit. In debugging, I can see that the exception is 'received' by the python interpreter, but it doesn't cause an exit.
Are you sure? Exceptions do normally cause the program to exit. The following never reaches the print statement.
class MyError(Exception):
pass
raise MyError
print("survived")
If you see different results, it must be because you are doing something else. Add your code to your question if you still can't see what you are doing wrong.
could you please help me to understand what is the difference between these 2 syntaxes in Django tests (Python 3.7):
def test_updateItem_deletion(self):
# some logic in here
with self.assertRaises(OrderItem.DoesNotExist):
OrderItem.objects.get(id=self.product_1.id)
And:
# all the same, but self.assertRaises not wrapped in 'with'
self.assertRaises(OrderItem.DoesNotExist, OrderItem.objects.get(id=self.product_1.id))
The first one worked and test passed. But the second one raised:
models.OrderItem.DoesNotExist: OrderItem matching query does not exist.
Does it somehow replicate the behaviour of try/catch block?
Thank you a lot!
The first one will catch the exception raised if executed as context manager.
On the second one, nothing is catching the exception.
This is known as ContextManager. When using the with statement, an __exit__ method is called at the end of the with block, containing any exception raised during execution of the block.
This __exit__ method is not called when directly calling assertRaises, so the exception is not captured.
Here you will find more info about this:
Official Doc
Python Tips
Suppose I have a simple function. For example:
def if_a_float(string):
try:
float(string)
except ValueError:
return False
else:
return True
Should I include the Raises: ValueError statement into my docstring or should I avoid it as the error was already handled in the code? Is it done for any error (caught/uncaught)? I do understand that it probably depends on the style, so let's say I am using the Google Docstring style(though I guess it doesn't matter that much)
You should document the exception raised explicitly, as well as those that may be relevant to the interface, as per the Google Style Guidelines (the same document you mention yourself).
This code does not raise an exception explicitly (there is no raise), and you do not need to mention that you are catching one.
Actually, this code cannot even accidentally raise one (you are catching the only line that could) and therefore it would be misleading if you were to document that the if_a_float() was raising a ValueError.
You should only document the exceptions that callers need to be aware of and may want to catch. If the function catches an exception itself and doesn't raise it to the caller, it's an internal implementation detail that callers don't need to be aware of, so it doesn't need to be documented.
I am developing a program in python and have reached a point I don't know how to solve.
My intention is to use a with statement, an avoid the usage of try/except.
So far, my idea is being able to use the continue statement as it would be used inside the except. However, I don't seem to succeed.
Let's supposse this is my code:
def A(object):
def __enter__:
return self
def __exit__:
return True
with A():
print "Ok"
raise Exception("Excp")
print "I want to get here"
print "Outside"
Reading the docs I have found out that by returning True inside the __exit__ method, I can prevent the exception from passing, as with the pass statement. However, this will immediately skip everything left to do in the with, which I'm trying to avoid as I want everything to be executed, even if an exception is raised.
So far I haven't been able to find a way to do this. Any advice would be appreciated.
Thank you very much.
It's not possible.
The only two options are (a) let the exception propagate by returning a false-y value or (b) swallow the exception by returning True. There is no way to resume the code block from where the exception was thrown. Either way, your with block is over.
You can't. The with statement's purpose is to handle cleanup automatically (which is why exceptions can be suppressed when exiting it), not to act as Visual Basic's infamous On Error Resume Next.
If you want to continue the execution of a block after an exception is raised, you need to wrap whatever raises the exception in a try/except statement.
Though most of the answers are correct, I'm afraid none suits my problem (I know I didn't provide my whole code, sorry about that).
I've solved the problem taking another approach. I wanted to be able to handle a NameError ("variable not declared") inside a With. If that occurred, I would look inside my object for that variable, and continue.
I'm now using globals() to declare the variable. It's not the best, but it actually works and let's the with continue as no exception is being risen.
Thank you all!
I am struggling a bit with the Python C API. I am calling a python method to do some game AI at about 60hz. It works most of the time but every second or so the call to PyEval_CallObject results in a NULL return value. If I correctly detect the error and continue looping, all is well for the next second or so, whereupon the error occurs again.
I suspect I am doing something wrong with ref counting but I can't figure out what it is:
int script_do_ai(struct game_data_t* gd)
{
PyObject *pAiModule, *pResult;
float result=0.0;
pResult = NULL;
pAiModule = PyImport_Import(PyString_FromString("ai_script"));
Yeah, I'm importing the the module every iteration. Is that necessary? If I store pAiModule as a global, I get a hard crash after about a second.
pResult = PyEval_CallObject(PyObject_GetAttrString(pAiModule, "do_ai"),
Py_BuildValue("f", gd->important_float))
if (pResult != NULL)
{
PyArg_Parse(pResult, "f", &result);
Py_DECREF(pResult);
ConquerEnemies(result); //you get the idea
}
else //this happens every 75 or so iterations thru the loop
{
if (PyErr_ExceptionMatches(PyExc_SomeException)) //? not sure what to do here
{
I haven't been able to find out how to extract the exception yet, either...without testing for every exception
}
}
Am I even close to doing this right? Like I said, it mostly works but I'd really like to understand why I am getting an error.
Thank you in advance for any help.
You can call PyImport_Import() as often as you like, but you'll just keep getting the same module object back. Python caches imports. Also, instead of creating a new Python string and leaking the reference (and thus the object), you should just use PyImport_ImportModule(), which takes a const char *.
PyImport_Import*() return a new reference, though, you should call Py_DECREF() on it when you're done. Storing the module in a global should not be a problem, as long as you own a reference to it (which you do, here.)
In your call to PyEval_CallObject() you aren't checking the result of Py_BuildValue() for errors, and you're also not calling Py_DECREF() when you're done with it, so you're leaking that object as well.
In order to convert a Python float to a C double, you should probably just call PyFloat_AsDouble() instead of mucking about with PyArg_Parse() (and keep in mind to test for exceptions)
Down to the actual error handling: PyErr_ExceptionMatches() is only useful when you actually want to test if the exception matches something. If you want to know if an exception occurred, or get the actual exception object, PyErr_Occurred() is what you should call. It returns the current exception type (not the actual exception object) as a borrowed reference, or NULL if none is set. If you want to just print a traceback to stderr, PyErr_Print() and PyErr_Clear() are what you want to use. For more fine-grained inspection of the actual error in your code, PyErr_Fetch() gets you the current exception object and the traceback associated with it (it gets you the same information as sys.exc_info() in Python code.) All things considered you rarely want to get that deeply into the exception handling in C code.