Flutterando / modular

A smart project structure
https://pub.dev/packages/flutter_modular
Other
1.3k stars 252 forks source link

How to wrap all Resource functions in the same error handling function in order to reduce boilerplate? (Sheld_Modular) #940

Open ember11498 opened 7 months ago

ember11498 commented 7 months ago

Inside a Resource class I have this snippet code:

@override
List<Route> get routes => [
        Route.get('/login', _login),
        Route.get('/refresh-token', _refreshToken,
            middlewares: [AuthGuard(isRefreshToken: true)]),
        Route.get('/check-stauts/:refresh', _checkStatus),
    ];

Lets say every function (login, refreshToken. checkStatus aswell as other function in other Resource classes) all share the same error handling treatment. for simplicity lets say its

try { // execute function code } catch(e) { return Response.internalServerError(); }

Instead of using all this boiler plate in each function I wanted to know if there is a way to wrap every function inside another one that would do the error handling like per example:

Function handleErrors(Function handler) {
return () {
    try {
    return handler();
    } catch (e) {
    print(e);
    return Response.internalServerError();
    }
};
}

and then I would call the function like:

@override
List<Route> get routes => [
        Route.get('/login', handleErrors(_login)),
        Route.get('/refresh-token', handleErrors(_refreshToken),
            middlewares: [AuthGuard(isRefreshToken: true)]),
        Route.get('/check-stauts/:refresh', handleErrors(_checkStatus)),
    ];

The problem here is that I get the error "type 'Response' is not a subtype of type 'Function'"

I believe the error is that I cannot call the functions inside the @override routes. I need to just pass functions like _login and not _login() per example.

So, is there a way to reduce the errorHandling boilerplate?

NoSuchMethodError: Closure call with mismatched arguments: function 'EmailVerifyEndPoint._checkCode' Receiver: Closure: (Injector, ModularArguments) => FutureOr from Function '_checkCode@195052454':. Tried calling: EmailVerifyEndPoint._checkCode() Found: EmailVerifyEndPoint._checkCode(Injector, ModularArguments) => FutureOr Unhandled exception: type 'Response' is not a subtype of type 'Function'

ember11498 commented 7 months ago

O ideal era dar user um errorHandlingWrapper aqui nesta função:

FutureOr<Response>? applyHandler(
Function fn, {
required Request request,
required ModularArguments arguments,
required AutoInjector injector,
}) {
//less
if (fn is HandlerWithlessParams) {
    return fn();
} else if (fn is Handler) {
    return fn(request);
} else if (fn is Handler1) {
    return fn(arguments);
} else if (fn is Handler2) {
    return fn(injector);
} else if (fn is HandlerTwoParams) {
    return fn(request, arguments);
} else if (fn is HandlerTwoParams1) {
    return fn(request, injector);
} else if (fn is HandlerTwoParams2) {
    return fn(arguments, request);
} else if (fn is HandlerTwoParams3) {
    return fn(arguments, injector);
} else if (fn is HandlerTwoParams4) {
    return fn(injector, arguments);
} else if (fn is HandlerTwoParams5) {
    return fn(injector, request);
} else if (fn is HandlerThreeParams) {
    return fn(request, arguments, injector);
} else if (fn is HandlerThreeParams1) {
    return fn(request, injector, arguments);
} else if (fn is HandlerThreeParams2) {
    return fn(arguments, request, injector);
} else if (fn is HandlerThreeParams3) {
    return fn(arguments, injector, request);
} else if (fn is HandlerThreeParams4) {
    return fn(injector, arguments, request);
} else if (fn is HandlerThreeParams5) {
    return fn(injector, request, arguments);
} else {
    return null;
}
}
ember11498 commented 7 months ago

Se calhar tenho que criar uma extension on Routes ou extension noutra parte.

e usava tipo assim:

Route.get('/check-stauts/:refresh', _checkStatus).wrapHandler(_handleErrors),

extension CustomRouteExtension on Route {
Route wrapHandler() {
    return Route.copy(this)..handler = () async {
    try {
        return this.handler;
    } catch (e) {
        print(e);
        return Response.internalServerError();
    }
    };
}
}

a extension esta mal escrita porque eu não sei bem fazer ainda. mas só para passar a ideia