from socketio.namespace import BaseNamespace
from tg.predicates import NotAuthorizedError
from tg.decorators import Decoration
from tg._compat import default_im_func
from crank.util import get_params_with_argspec
from tg.controllers.decoratedcontroller import DecoratedController
from tg.validation import validation_errors, TGValidationError


class UnsupportedTGVersionException(Exception):
    pass


class SocketIOTGNamespace(BaseNamespace):
    def is_method_allowed(self, method_name):
        method = getattr(self, method_name, None)
        if method is None:
            return True # method not found case handled later

        deco = Decoration.get_decoration(default_im_func(method))
        try:
            requirement = deco.requirement
        except AttributeError:
            raise UnsupportedTGVersionException('tgext.socketio requires at least '
                                                'TurboGears 2.3.1')

        if requirement is None:
            return super(SocketIOTGNamespace, self).is_method_allowed(method_name)

        predicate = requirement.predicate
        if predicate is None:
            return False

        try:
            predicate.check_authorization(self.request.environ)
        except NotAuthorizedError as e:
            return False

        return super(SocketIOTGNamespace, self).is_method_allowed(method_name)

    def call_method(self, method_name, packet, *args):
        method = getattr(self, method_name, None)
        if method is not None:
            deco = Decoration.get_decoration(default_im_func(method))
            validation = deco.validation
            if validation:
                validate_params = get_params_with_argspec(method, {}, args)

                try:
                    params = DecoratedController._perform_validate(method, validate_params)
                except TGValidationError as inv:
                    error_dict = dict((key, str(error)) for key,error in inv.error_dict.items())
                    self.error("invalid_method_args", error_dict)
                    return
                except validation_errors as inv:
                    self.error("invalid_method_args", str(inv))
                    return

                # Check if we need to decorate to handle exceptions
                if hasattr(self, 'exception_handler_decorator'):
                    method = self.exception_handler_decorator(method)

                return method(**params)

        return super(SocketIOTGNamespace, self).call_method(method_name, packet, *args)
@@ -1859,34 +1859,576 @@
 ept 
-TGValidationError as inv:%0A
+validation_errors as inv:%0A                    if deco.validation.error_handler:%0A                        handler, output = DecoratedController._handle_validation_errors(method,%0A                                                                                        args, %7B%7D,%0A                                                                                        inv, self)%0A                        return output%0A                    else:%0A                        if isinstance(inv, TGValidationError):%0A                            error_dict = inv.error_dict.items()%0A    
     
@@ -2435,32 +2435,36 @@
                 
+    
 error_dict = dic
@@ -2500,20 +2500,16 @@
 rror in 
-inv.
 error_di
@@ -2514,18 +2514,14 @@
 dict
-.items())%0A
+)%0A    
     
@@ -2528,32 +2528,36 @@
                 
+    
 self.error(%22inva
@@ -2610,64 +2610,26 @@
     
-return%0A                except validation_errors as inv:%0A
+    else:%0A        
     
@@ -2688,16 +2688,20 @@
 r(inv))%0A
+    
         

Use also error_handler for @validate