4723: Djblets should allow decorated methods to use exceptions for response errors

jcannon

What version are you using?

master

Which module(s) does this relate to?

decorators.py

Describe the enhancement and the motivation for it.

I have a decorated method that might respond with some errors, but those errors are generated in a helper method. There's no natural way for me to write the helper method to return error-or-data.
The decorated method should be able to raise djblets.ResponseError(err, info) to mean error, and just return info (which it turns into (201, info)).

This would greatly improve the code flow of the decorated methods.

Please provide any additional information below.

david
#1 david

Which decorators.py are you talking about? And which decorator methods inside of that?

It might be helpful to see an example of what you're looking to do.

  • -New
    +NeedInfo
jcannon
#2 jcannon

decorators.py is djblets/webapi/decorators.py and is just the relvant djblits module.
Example is:

class MyResource(WebAPIResource):
   # ...
   @webapi_response_errors(INVALID_FORM_DATA)
   @webapi_request_fields(...)
   def create(self, data1, data2):
      data1 = self._helper(data1)
      data2 = self._helper(data2)
      return 201, {...}

   def _helper(self, data):
      if 'my_key' not in data:
         # I can't return the error here, or else the caller would
         # need to check for it.
         # It would be nice if I could raise ResponseError(INVALID, ...)
         # Or even better, rase InvalidFormData(...)
         error()
      return {...}
david
#3 david

That seems like it's probably a niche use-case. It might be better to just have your own exception handler:

class FieldException(Exception):
    ...


class MyResource(WebAPIResource):
    @webapi_response_errors(INVALID_FORM_DATA):
    @webapi_request_fields(...)
    def create(self, data1, data2):
        try:
            data1 = self._helper(data1)
            data2 = self._helper(data2)
            return 201, {...}
        except FieldException as e:
            return INVALID_FORM_DATA, {...}

    def _helper(self, data):
        if 'my_key' not in data:
            raise FieldError(...)
jcannon
#4 jcannon

That's just one example. The real issue is using the same channel (the return value) for errors and results, which results in a very flat and lengthy method.

If you don't thing it's desirable feel free to close the ticket, though.