Guidance on using exceptions

39 views
Skip to first unread message

da...@spinshell.com

unread,
Apr 1, 2016, 5:25:47 AM4/1/16
to Autobahn
Hi,

Is there any guidance on how exceptions should be used in a WAMP application?

What I've been able to piece together so far:

- all application level exceptions should derive from autobahn.wamp.exception.ApplicationError
- all ApplicationErrors should have a defined URI for the type of error, like com.example.error.foo
- the autobahn.wamp.uri.error decorator seems to do... nothing?!

In particular I'm rather confused about that last point; I can't seem to see any point in using that decorator.

Would I be correct in simply defining a bunch of possible errors like so:

class FooError(ApplicationError):
   
def __init__(self, *args, **kwargs):
       
super().__init__('com.example.error.foo', *args, **kwargs)

And raise them in any method:

@register('com.example.bar')
def bar(self):
   
raise FooError

Best,
David

Tobias Oberstein

unread,
Apr 2, 2016, 11:56:49 AM4/2/16
to autob...@googlegroups.com
Hi David,

Am 01.04.2016 um 11:25 schrieb da...@spinshell.com:
> Hi,
>
> Is there any guidance on how exceptions should be used in a WAMP
> application?

Sadly, not.

>
> What I've been able to piece together so far:
>
> - all application level exceptions should derive from
> autobahn.wamp.exception.ApplicationError

Correct.

> - all ApplicationErrors should have a defined URI for the type of error,
> like com.example.error.foo

Yep.

> - the autobahn.wamp.uri.error decorator seems to do... nothing?!

Nope;)

It does something. Eg

https://github.com/crossbario/autobahn-python/blob/master/examples/twisted/wamp/rpc/errors/frontend.py

Given a custom exception:

@wamp.error(u"com.myapp.error1")
class AppError1(Exception):


you can do

self.define(AppError1)

on your WAMP session, and the do

try:
yield self.call(u'com.myapp.compare', 3, 17)
except AppError1 as e:
print("Compare Error: {}".format(e))


That is, Autobahn will auto-map the incoming error not to a general
ApplicationError (as is the default behavior), but directly to your
custom error class.

Please let me know if that helps / makes sense,
Cheers,
/Tobias

>
> In particular I'm rather confused about that last point; I can't seem to
> see any point in using that decorator.
>
> Would I be correct in simply defining a bunch of possible errors like so:
>
> |
> classFooError(ApplicationError):
> def__init__(self,*args,**kwargs):
> super().__init__('com.example.error.foo',*args,**kwargs)
> |
>
> And raise them in any method:
>
> |
> @register('com.example.bar')
> defbar(self):
> raiseFooError
> |
>
> Best,
> David
>
> --
> You received this message because you are subscribed to the Google
> Groups "Autobahn" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to autobahnws+...@googlegroups.com
> <mailto:autobahnws+...@googlegroups.com>.
> To post to this group, send email to autob...@googlegroups.com
> <mailto:autob...@googlegroups.com>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/autobahnws/d5846d9d-ccc2-4e02-971d-78e9f8188caf%40googlegroups.com
> <https://groups.google.com/d/msgid/autobahnws/d5846d9d-ccc2-4e02-971d-78e9f8188caf%40googlegroups.com?utm_medium=email&utm_source=footer>.
> For more options, visit https://groups.google.com/d/optout.

David C. Zentgraf

unread,
Apr 4, 2016, 3:45:29 AM4/4/16
to autob...@googlegroups.com
Hi Tobias,

Thanks a lot for that explanation, that makes a lot of sense. The elusive .define() was the missing piece of the puzzle... :)

BTW, I've added some automatic (de)serialisation of classes for my app, which allows WAMP endpoints to receive native objects directly. E.g.:

@register('com.example.foo')
def foo(self, bar: BarClass) -> BazClass:
baz = bar.doSomething()
return baz

To alleviate your concerns about being too language-specific: those objects are simply converted to/from simple JSON values behind the scenes.

The @error decorator seems to go very much in the same direction already, so how about formalising this capability into a decorator as well? E.g.:

@register('com.example.foo')
@param('bar', unserializer=BarClass.fromJSON)
@return(serializer=BazClass.toJSON)
def foo(self, bar: BarClass) -> BazClass:
...

With Python 3.4+ type annotations this could even mostly happen behind the scenes if the classes implement a specific interface...
Just an idea to throw out there...

Best,
Dav
> You received this message because you are subscribed to a topic in the Google Groups "Autobahn" group.
> To unsubscribe from this topic, visit https://groups.google.com/d/topic/autobahnws/hxJe4aIMLQU/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to autobahnws+...@googlegroups.com.
> To post to this group, send email to autob...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/autobahnws/56FFEBBE.3080000%40gmail.com.

Tobias Oberstein

unread,
Apr 4, 2016, 4:38:20 AM4/4/16
to autobahnws

Hi David,

oh, this automatic marshalling is interesting! Yes, this is same direction as the error decorators. So yes, this is probably something that would be a nice addition to Autobahn. Do you have a stripped down example somewhere? In any case, would be cool if you could file an issue, describe your use case and what you did ..

Cheers,
/Tobias

Sent from Mobile (Google Nexus 5)

To unsubscribe from this group and stop receiving emails from it, send an email to autobahnws+...@googlegroups.com.

To post to this group, send email to autob...@googlegroups.com.

David C. Zentgraf

unread,
Apr 4, 2016, 5:12:43 AM4/4/16
to autob...@googlegroups.com
Reply all
Reply to author
Forward
0 new messages