Should Python errors be documented in code or comments? - python

Let's say we have a service method that performs its business logic by using one or more helper methods, where each helper method can raise one or more errors.
Because there can potentially be many helper methods that in total encapsulate lots of code, we want a way for folks using the service method to know all of the errors it can raise without needing to read through the implementation of every helper method.
To make this more concrete, let's assume this is being done in a Django context, where each view calls a service method, and then that view is then responsible for catching any errors the service method raises and returning an appropriate response for each to the user.
So question is, should the errors that each helper method can raise be documented by just re-raising the errors using a try/except, or should they be noted in a docstring?
For example, which is better here, service_method_v1 or service_method_v2?:
def service_method_v1():
try:
helper_method_1()
except SomeError:
raise
def service_method_v2():
"""
Raises:
SomeError, via helper_method_1()
"""
helper_method_1()
helper_method_1():
raise SomeError
I know there is some computational overhead when using try/except, but this purpose let's assume that this is negligible in terms of the end user experience.

Related

How expensive is raise in Python?

During development using drf, an efficient method for error handling was needed.
I found two methods, one using ErrorResponse created by inheriting Response, and one using APIException provided by drf.
The first method is done through return, and the second method uses the raise command.
I wonder which one is more efficient and why!
I apologize in advance for the question may be too vague.
Not sure if efficiency and CPU time is most important thing.
You have to understand Django request-response cycle first. The next step after return Response (or raise Exception) is not a client side browser but number of Middlewares that you imported in your application. And these Middlewares may be different depends on what happens inside View.
When you raising something you break this cycle flow.
Django handling raised exception, writing extra error logs, returning specified error response to client side. You don't have to care that all conditions of correct responses will be satisfied, because error already happens, it is already not correct. In other way returned Response will be delivered to client side by normal way. Django will care that all validations and steps will be passed before response reach a client.
If you need to save milliseconds by choosing between return / raise and deeply thinking about efficiency, at first stop using Django. Seriously. It is slowest framework even for python.
raise produces an error in the current level of the call stack. You can catch a raised error by covering the area where the error might be raised in a try and handling that error in an except.
return on the other hand, returns a value to where the function was called from, so returning an exception usually is not the functionality you are looking for in a situation like this, since the exception itself is not the thing triggering the except it is instead the raising of the exception that triggers it.
https://docs.python.org/3/reference/simple_stmts.html#raise
https://docs.python.org/3/reference/simple_stmts.html#return
So to answer your question I would raise because it is built for errors compared to return. Also, they are the same in speed/efficiency.

Security issue in catching exceptions in outside methods? Python

Is there a security issue in catching exceptions through a separate function? For example if I catch an exception in class:
def my_function(some_variable):
try:
int(some_variable)
except ValueError:
sys.exit()
#other code running
As opposed to passing it through some sort of method.
def my_function(some_variable)
check_error(some_variable) #this does the try/except
#other code running
def check_error(some_variable)
#does the check
Is there a flaw or vulnerability that can be exploited in one or the other, by memory, etc, or is the two methods shown above essentially the same thing. I believe that python deals with all memory handling automatically. I could be wrong. However, I want to know is there a reason why it is good practice to catch exceptions in method or in an outside method as shown in the two code samples above.
I understand if there is a lot of checking it is good for an exception method for readability and modularity, but is it good for security?
Also this might be a better question to put in chat, but I don't have that capability yet. Thanks in advance.

How to wrap functions in try/except and require a parameter

I want to wrap a bunch of functions in a try/except and have them email me a traceback when they fail. I'm using Django's ExceptionReporter, so I need the request object to send the traceback email. Some of the functions I want to wrap have the request object as a parameter already, but not all of them.
I was thinking about using a decorator for the try/except, but then it isn't clear that the request object is a required parameter for all the functions it decorates. Is there a better way to do this?
Edit: The functions I'm trying to wrap are all just supplementary functions after the core stuff required for the response are done, so I don't want to use Django's automatic emailing that happens when returning a 500 error because of an uncaught exception. I suppose that opens up the possibility of running these methods as separate processes after returning the response, but that also gets complicated in Django.

Can I change the behaviour of "raise" or "Exception"? [duplicate]

This question already has answers here:
Calling a hook function every time an Exception is raised
(4 answers)
Closed 6 years ago.
My project's code is full of blocks like the following:
try:
execute_some_code()
except Exception:
print(datetime.datetime.now())
raise
simply because, if I get an error message, I'd like to know when it happened. I find it rather silly to repeat this code over and over, and I'd like to factor it away.
I don't want to decorate execute_some_code with something that does the error capturing (because sometimes it's just a block of code rather than a function call, and sometimes I don't need the exact same function to be decorated like that). I also don't want to divert stdout to some different stream that logs everything, because that would affect every other thing that gets sent to stdout as well.
Ideally, I'd like to over-ride the behaviour of either the raise statement (to also print datetime.datetime.now() on every execution) or the Exception class, to pre-pend all of its messages with the time. I can easily sub-class from Exception, but then I'd have to make sure my functions raise an instance of this subclass, and I'd have just as much code duplication as currently.
Is either of these options possible?
You might be able to modify python (I'd have to read code to be sure how complex that'd be), but:
You do not want to replace raise with different behaviour - trying and catching is a very pythonic approach to problem solving, so there's lots of code that works very well by e.g. calling a method and letting that method raise an exception, catching that under normal circumstances. So we can rule that approach out – you really only want to know about the exceptions you care about, not the ones that are normal during operation.
The same goes for triggering some action whenever an Exception instance is created – but:
You might be able to overwrite the global namespace; at least for things that get initialized after you declared your own Exception class. You could then add a message property that includes a timestamp. Don't do that, though – there might be people actually relying on the message to automatically react to Exceptions (bad style, but still not really seldom, sadly).

Should a validate method throw an exception?

I've implemented a little validation library which is used like this:
domain_object.validate()
# handle validation errors in some way ...
if domain_object.errors:
for error in domain_object.errors:
print(error)
validate() performs the checks and populates a list called errors.
I know from other validation libraries that they throw exception when validation is performed unsuccessfully. Error messages would be passed as an exception property.
What approach is better? Is it advantageous to throw validation exceptions?
No, I wouldn't think that a validation method should throw an exception.
That would create a bit of an anti-pattern, as the client code calling the method would reasonably expect an exception to be thrown, and would then need to catch the exception. Since it's generally recommended that exceptions not be used for flow control, why not just return a value indicating whether validation was successful or not. The client code could check the return value and proceed accordingly.
You essentially accomplish the same thing as you would by throwing an exception, but without the extra cost and poor semantics of actually throwing an exception.
Exceptions should be reserved for truly exceptional conditions, not normal operation of a program. Failing validation to me seems like it is a pretty normal condition, something to be expected during the day-to-day operation of an application. It would be easily handled by the calling code, and normal operation would continue. Generally, that's not the case with exceptions.
I argue for the exact opposite: In a validation layer you want to ensure that every validation error is handled. If you rely on return values, there might be a bug in the integration code (especially when you use the validators in a different environment).
Python exceptions will make that problem obvious.

Categories

Resources