Skip to content
This repository has been archived by the owner on Jan 29, 2020. It is now read-only.

Allow opt-in to raising exceptions instead of error middleware #78

Conversation

weierophinney
Copy link
Member

This patch implements the features suggested in #77. Specifically, it adds a "raise throwables" flag that may be set on each of the MiddlewarePipe, Next, and Dispatch instances; setting it on one enables it on each layer deeper:

  • Setting it on Dispatch only enables it on that instance.
  • Setting it on Next also enables it on Dispatch.
  • Setting it on MiddlewarePipe also enables it on Next and Dispatch.

The flag is toggled off by default (current 1.0 behavior), and cannot be disabled once enabled.

Once enabled:

  • Dispatch will not wrap middleware dispatch in a try/catch block.
  • Next, when presented with an $err argument will:
    • throw the argument, if throwable.
    • raise a deprecation notice otherwise, and then create a Zend\Stratigility\Exception\MiddlewareException based on the $err value.
  • MiddlewarePipe will enable the flag on Next instances it creates (and thus the Dispatch instances).

The end result is that, if enabled on the outermost application pipeline, you will now have the 2.0 error handling mechanism in place: middleware raises exceptions, and outer middleware catches these and does something with them.

This feature will allow Expressive, for instance, to opt-in to the feature in the next minor version, while providing default error handling mimicing what it already provides via the FinalHandler implementation, without breaking backwards compatibility.

When enabled, any middleware dispatch is no longer wrapped in try/catch
blocks, allowing for exceptions/throwables to bubble out.
Added `$raiseThrowables` property and `raiseThrowables()` method, with
the former defaulting to `false` for backwards compatibility.

Has the following behavior:

- Enables the same flag in the `Dispatch` instance composed.
- If enabled and `$err` is passed to `__invoke()`:
  - Throwable/Exception values are simply thrown.
  - String arguments are used as the message for a new `MiddlewareException`.
  - Scalar values are reported in a new `MiddlewareException`
  - Array value *types* are reported in a new `MiddlewareException`
  - Object *types* are reported in a new `MiddlewareException`
  - Non-throwable/exception types trigger the deprecation notice
- Disabled by default
- `raiseThrowables()` enables it
- When enabled, calls same method on `Next` instance after creating it
weierophinney added a commit to weierophinney/zend-stratigility that referenced this pull request Nov 7, 2016
…ndling-v2

Forward-ports zendframework#78 to dev-2.0.0.

Conflicts:
	src/Dispatch.php
	src/MiddlewarePipe.php
	src/Next.php
	test/DispatchTest.php
	test/NextTest.php
@weierophinney weierophinney added this to the 1.3.0 milestone Nov 7, 2016
Copy link
Member

@geerteltink geerteltink left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Besides possible missing tests, looks good to me.

@@ -28,6 +28,14 @@
class Dispatch
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Import Interop\Http\Middleware\DelegateInterface is not used. However it is mentioned as a comment in the docblock right before the process method, but I don't think that's a reason to import it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, removed now.

@@ -193,6 +212,18 @@ private function dispatchCallableMiddleware(
break;
}

if ($this->raiseThrowables) {
if ($hasError && $arity === 4) {
return $middleware($err, $request, $response, $next);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not tested. Not sure if it's needed though.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably not, as it's the same workflow as what's in the try/catch block... and we're recommending against using error middleware starting in this version anyways.

return $middleware($request, $response, $next);
}

return $next($request, $response, $err);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests are missing for this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests have now been added for both this path, and the one noted above.

Ensure all paths in Dispatch are covered.
weierophinney added a commit to weierophinney/zend-stratigility that referenced this pull request Nov 8, 2016
…ndling-v2

Forward port changes made for zendframework#78 (in this case, tests that are no
longer applicable).

Conflicts:
	test/DispatchTest.php
weierophinney added a commit to weierophinney/zend-stratigility that referenced this pull request Nov 8, 2016
…ndling-v2

Forward port changes from zendframework#78.

Conflicts:
	src/Dispatch.php
@weierophinney weierophinney merged commit 01b9fb3 into zendframework:develop Nov 8, 2016
weierophinney added a commit that referenced this pull request Nov 8, 2016
weierophinney added a commit that referenced this pull request Nov 8, 2016
@weierophinney weierophinney deleted the feature/error-handling-poka-yoke branch November 8, 2016 20:24
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
v2
Complete
Development

Successfully merging this pull request may close these issues.

None yet

2 participants