Guidance on using exceptions

#1

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

0 Likes

#2

Hi David,

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

···

Am 01.04.2016 um 11:25 schrieb da...@spinshell.com:

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.

0 Likes

#3

Hi Tobias,

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

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

···

On 02 Apr 2016, at 17:56, Tobias Oberstein <tobias.o...@gmail.com> wrote:

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.

--
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.
For more options, visit https://groups.google.com/d/optout.

0 Likes

#4

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)

Am 04.04.2016 9:45 vorm. schrieb “David C. Zentgraf” da...@spinshell.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… :slight_smile:

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

On 02 Apr 2016, at 17:56, Tobias Oberstein tobias.o...@gmail.com wrote:

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.

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.

For more options, visit https://groups.google.com/d/optout.

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.

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/1C38CC30-20A9-4A7B-8403-11FC3A7C4773%40spinshell.com.

For more options, visit https://groups.google.com/d/optout.

0 Likes

#5

Posted a ticket for now to capture the idea:
https://github.com/crossbario/autobahn-python/issues/624

Best,
Dav

···

On 04 Apr 2016, at 10:38, Tobias Oberstein <tobias.o...@gmail.com> wrote:

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)

Am 04.04.2016 9:45 vorm. schrieb "David C. Zentgraf" <da...@spinshell.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... :slight_smile:

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

> On 02 Apr 2016, at 17:56, Tobias Oberstein <tobias.o...@gmail.com> wrote:
>
> 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.
>
> --
> 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.
> For more options, visit https://groups.google.com/d/optout.

--
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.
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/1C38CC30-20A9-4A7B-8403-11FC3A7C4773%40spinshell.com.
For more options, visit https://groups.google.com/d/optout.

--
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/CABuE%2BY4ownoNnAEg7i7pvP47wNf0ZcN7fpQ-mx143u0f5mjiOg%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

0 Likes