-
-
Notifications
You must be signed in to change notification settings - Fork 930
Description
Feature request
From #6813
I recently tried to create something where this would have been quite useful: a higher-order function to take functions that throw exceptions, catch (and log) them, and then return a WP_Error object instead.
/**
* Wraps a function so that, when run, any exceptions are caught, logged, and converted to a generic WP_Error.
*
* Works with functions of up to 5 parameters. (Add more PX generic types to this docblock to add support for more params.)
*
* @template P1
* @template P2
* @template P3
* @template P4
* @template P5
* @template R
*
* @param (Closure(P1, P2, P3, P4, P5): R) $fn Function that could throw.
*
* @return (Closure(P1, P2, P3, P4, P5): (R|WP_Error))
*/
function handleExceptionsAsWpErrors(Closure $fn, LoggerInterface $logger): Closure {
return static function (...$params) use ($fn, $logger) {
try {
return $fn(...$params);
} catch (Throwable $e) {
$logger->error($e->getMessage());
return new WP_Error('arn_internal_server_error');
}
};
}
In this case, I was hoping that I could get around the issue of having variable numbers of params by hardcoding generics for a reasonable max number of parameters. My hope was that, that for Closures with less than 5 params, the unused PX
template types would default to never
, and Closure(never): R
would be considered identical to Closure(): R
.
Of course, it didn't actually work when I tried it, and I suspect that not even setting explicit defaults for the template types (once #1835 lands) would alter the behavior here.
But should it work? Is a parameter of type never
the same thing as no parameter at all? Or would that conceptually be more like a void
parameter, if such a thing even makes sense?
It's also worth noting that TypeScript has a Parameters
utility type. Presumably, if PHPStan had something like this, the kind of static typing I'm looking for would be straightforward, using syntax that could look a little like this:
/**
* @template R
*
* @param (Closure(...): R) $fn
*
* @return (Closure(...parameters<$fn>): (R|WP_Error))
*/
What do you think of these ideas?
Originally posted by @ZebulanStanphill in #6813 (comment)