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

Commit 1a2d418

Browse files
committed
Merge branch 'hotfix/use-constants-not-virtual-services' into release-3.0.0
Close #562
2 parents ab064f2 + 457bc1f commit 1a2d418

12 files changed

+429
-142
lines changed

CHANGELOG.md

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@ All notable changes to this project will be documented in this file, in reverse
66

77
### Added
88

9-
- Nothing.
9+
- [#562](https://github.com/zendframework/zend-expressive/pull/562) adds the
10+
class `Zend\Expressive\Response\ServerRequestErrorResponseGenerator`, and maps
11+
it to the `Zend\Expressive\Container\ServerRequestErrorResponseGeneratorFactory`.
12+
The class generates an error response when an exeption occurs producing a
13+
server request instance, and can be optionally templated.
1014

1115
### Changed
1216

@@ -20,13 +24,28 @@ All notable changes to this project will be documented in this file, in reverse
2024
creates, as that class changes in 3.0.0alpha4 such that it now expects a
2125
factory instead of an instance.
2226

27+
- [#562](https://github.com/zendframework/zend-expressive/pull/562) modifies the
28+
`Zend\Expressive\Container\RequestHandlerRunnerFactory` to depend on the
29+
`Zend\Expressive\Response\ServerRequestErrorResponseGenerator` service instead
30+
of the `Zend\Expressive\SERVER_REQUEST_ERROR_RESPONSE_GENERATOR` virtual
31+
service.
32+
33+
- [#562](https://github.com/zendframework/zend-expressive/pull/562) extracts
34+
most logic from `Zend\Expressive\Middleware\ErrorResponseGenerator` to a new
35+
trait, `Zend\Expressive\Response\ErrorResponseGeneratorTrait`. A trait was
36+
used as the classes consuming it are from different namespaces, and thus
37+
different inheritance trees. The trait is used by both the
38+
`ErrorResponseGenerator` and the new `ServerRequestErrorResponseGenerator`.
39+
2340
### Deprecated
2441

2542
- Nothing.
2643

2744
### Removed
2845

29-
- Nothing.
46+
- [#562](https://github.com/zendframework/zend-expressive/pull/562) removes the
47+
constant `Zend\Expressive\SERVER_REQUEST_ERROR_RESPONSE_GENERATOR`. It was
48+
only used internally previously.
3049

3150
### Fixed
3251

src/ConfigProvider.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public function __invoke() : array
3232

3333
public function getDependencies() : array
3434
{
35+
// @codingStandardsIgnoreStart
3536
return [
3637
'aliases' => [
3738
DEFAULT_DELEGATE => Handler\NotFoundHandler::class,
@@ -53,10 +54,11 @@ public function getDependencies() : array
5354
Middleware\ErrorResponseGenerator::class => Container\ErrorResponseGeneratorFactory::class,
5455
RequestHandlerRunner::class => Container\RequestHandlerRunnerFactory::class,
5556
ResponseInterface::class => Container\ResponseFactoryFactory::class,
56-
SERVER_REQUEST_ERROR_RESPONSE_GENERATOR => Container\ServerRequestErrorResponseGeneratorFactory::class,
57+
Response\ServerRequestErrorResponseGenerator::class => Container\ServerRequestErrorResponseGeneratorFactory::class,
5758
ServerRequestInterface::class => Container\ServerRequestFactoryFactory::class,
5859
StreamInterface::class => Container\StreamFactoryFactory::class,
5960
],
6061
];
62+
// @codingStandardsIgnoreEnd
6163
}
6264
}

src/Container/RequestHandlerRunnerFactory.php

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,27 +12,26 @@
1212
use Psr\Container\ContainerInterface;
1313
use Psr\Http\Message\ServerRequestInterface;
1414
use Zend\Expressive\ApplicationPipeline;
15-
use Zend\Expressive\ServerRequestErrorResponseGenerator;
15+
use Zend\Expressive\Response\ServerRequestErrorResponseGenerator;
1616
use Zend\HttpHandlerRunner\Emitter\EmitterInterface;
1717
use Zend\HttpHandlerRunner\RequestHandlerRunner;
1818

1919
/**
2020
* Create an ApplicationRunner instance.
2121
*
22-
* This class consumes three pseudo-services (services that look like class
23-
* names, but resolve to other artifacts):
22+
* This class consumes two pseudo-services (services that look like class
23+
* names, but resolve to other artifacts) and two services provided within
24+
* this package:
2425
*
2526
* - Zend\Expressive\ApplicationPipeline, which should resolve to a
2627
* Zend\Stratigility\MiddlewarePipeInterface and/or
2728
* Psr\Http\Server\RequestHandlerInterface instance.
29+
* - Zend\HttpHandlerRunner\Emitter\EmitterInterface.
2830
* - Psr\Http\Message\ServerRequestInterface, which should resolve to a PHP
2931
* callable that will return a Psr\Http\Message\ServerRequestInterface
3032
* instance.
31-
* - Zend\Expressive\ServerRequestErrorResponseGenerator, which should resolve
32-
* to a PHP callable that accepts a Throwable argument, and which will return
33-
* a Psr\Http\Message\ResponseInterface instance.
33+
* - Zend\Expressive\Response\ServerRequestErrorResponseGeneratorFactory,
3434
*
35-
* It also consumes the service Zend\HttpHandlerRunner\Emitter\EmitterInterface.
3635
*/
3736
class RequestHandlerRunnerFactory
3837
{

src/Container/ServerRequestErrorResponseGeneratorFactory.php

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,29 @@
1111

1212
use Psr\Container\ContainerInterface;
1313
use Psr\Http\Message\ResponseInterface;
14-
use Throwable;
15-
use Zend\Diactoros\Response;
16-
use Zend\Diactoros\ServerRequest;
1714
use Zend\Expressive\Middleware\ErrorResponseGenerator;
15+
use Zend\Expressive\Response\ServerRequestErrorResponseGenerator;
16+
use Zend\Expressive\Template\TemplateRendererInterface;
1817

1918
class ServerRequestErrorResponseGeneratorFactory
2019
{
21-
public function __invoke(ContainerInterface $container) : callable
20+
public function __invoke(ContainerInterface $container) : ServerRequestErrorResponseGenerator
2221
{
23-
return function (Throwable $e) use ($container) : ResponseInterface {
24-
$generator = $container->get(ErrorResponseGenerator::class);
25-
return $generator($e, new ServerRequest(), new Response());
26-
};
22+
$config = $container->has('config') ? $container->get('config') : [];
23+
$debug = $config['debug'] ?? false;
24+
25+
$renderer = $container->has(TemplateRendererInterface::class)
26+
? $container->get(TemplateRendererInterface::class)
27+
: null;
28+
29+
$template = $config['zend-expressive']['error_handler']['template_error']
30+
?? ServerRequestErrorResponseGenerator::TEMPLATE_DEFAULT;
31+
32+
return new ServerRequestErrorResponseGenerator(
33+
$container->get(ResponseInterface::class),
34+
$debug,
35+
$renderer,
36+
$template
37+
);
2738
}
2839
}

src/Middleware/ErrorResponseGenerator.php

Lines changed: 17 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -12,38 +12,15 @@
1212
use Psr\Http\Message\ResponseInterface;
1313
use Psr\Http\Message\ServerRequestInterface;
1414
use Throwable;
15+
use Zend\Expressive\Response\ErrorResponseGeneratorTrait;
1516
use Zend\Expressive\Template\TemplateRendererInterface;
1617
use Zend\Stratigility\Utils;
1718

1819
class ErrorResponseGenerator
1920
{
20-
public const TEMPLATE_DEFAULT = 'error::error';
21-
22-
/**
23-
* @var bool
24-
*/
25-
private $debug;
26-
27-
/**
28-
* @var TemplateRendererInterface
29-
*/
30-
private $renderer;
31-
32-
/**
33-
* @var string
34-
*/
35-
private $stackTraceTemplate = <<<'EOT'
36-
%s raised in file %s line %d:
37-
Message: %s
38-
Stack Trace:
39-
%s
21+
use ErrorResponseGeneratorTrait;
4022

41-
EOT;
42-
43-
/**
44-
* @var string
45-
*/
46-
private $template;
23+
public const TEMPLATE_DEFAULT = 'error::error';
4724

4825
public function __construct(
4926
bool $isDevelopmentMode = false,
@@ -63,66 +40,21 @@ public function __invoke(
6340
$response = $response->withStatus(Utils::getStatusCode($e, $response));
6441

6542
if ($this->renderer) {
66-
return $this->prepareTemplatedResponse($e, $request, $response);
67-
}
68-
69-
return $this->prepareDefaultResponse($e, $response);
70-
}
71-
72-
private function prepareTemplatedResponse(
73-
Throwable $e,
74-
ServerRequestInterface $request,
75-
ResponseInterface $response
76-
) : ResponseInterface {
77-
$templateData = [
78-
'response' => $response,
79-
'request' => $request,
80-
'uri' => (string) $request->getUri(),
81-
'status' => $response->getStatusCode(),
82-
'reason' => $response->getReasonPhrase(),
83-
];
84-
85-
if ($this->debug) {
86-
$templateData['error'] = $e;
87-
}
88-
89-
$response->getBody()->write(
90-
$this->renderer->render($this->template, $templateData)
91-
);
92-
93-
return $response;
94-
}
95-
96-
private function prepareDefaultResponse(Throwable $e, ResponseInterface $response) : ResponseInterface
97-
{
98-
$message = 'An unexpected error occurred';
99-
100-
if ($this->debug) {
101-
$message .= "; strack trace:\n\n" . $this->prepareStackTrace($e);
102-
}
103-
104-
$response->getBody()->write($message);
105-
106-
return $response;
107-
}
108-
109-
/**
110-
* Prepares a stack trace to display.
111-
*/
112-
private function prepareStackTrace(Throwable $e) : string
113-
{
114-
$message = '';
115-
do {
116-
$message .= sprintf(
117-
$this->stackTraceTemplate,
118-
get_class($e),
119-
$e->getFile(),
120-
$e->getLine(),
121-
$e->getMessage(),
122-
$e->getTraceAsString()
43+
return $this->prepareTemplatedResponse(
44+
$e,
45+
$this->renderer,
46+
[
47+
'response' => $response,
48+
'request' => $request,
49+
'uri' => (string) $request->getUri(),
50+
'status' => $response->getStatusCode(),
51+
'reason' => $response->getReasonPhrase(),
52+
],
53+
$this->debug,
54+
$response
12355
);
124-
} while ($e = $e->getPrevious());
56+
}
12557

126-
return $message;
58+
return $this->prepareDefaultResponse($e, $this->debug, $response);
12759
}
12860
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
<?php
2+
/**
3+
* @see https://github.com/zendframework/zend-expressive for the canonical source repository
4+
* @copyright Copyright (c) 2018 Zend Technologies USA Inc. (https://www.zend.com)
5+
* @license https://github.com/zendframework/zend-expressive/blob/master/LICENSE.md New BSD License
6+
*/
7+
8+
declare(strict_types=1);
9+
10+
namespace Zend\Expressive\Response;
11+
12+
use Psr\Http\Message\ResponseInterface;
13+
use Throwable;
14+
use Zend\Expressive\Template\TemplateRendererInterface;
15+
16+
trait ErrorResponseGeneratorTrait
17+
{
18+
/**
19+
* Whether or not we are in debug/development mode.
20+
*
21+
* @var bool
22+
*/
23+
private $debug;
24+
25+
/**
26+
* @param TemplateRendererInterface
27+
*/
28+
private $renderer;
29+
30+
/**
31+
* @var string
32+
*/
33+
private $stackTraceTemplate = <<<'EOT'
34+
%s raised in file %s line %d:
35+
Message: %s
36+
Stack Trace:
37+
%s
38+
39+
EOT;
40+
41+
/**
42+
* Name of the template to render.
43+
*
44+
* @var string
45+
*/
46+
private $template;
47+
48+
private function prepareTemplatedResponse(
49+
Throwable $e,
50+
TemplateRendererInterface $renderer,
51+
array $templateData,
52+
bool $debug,
53+
ResponseInterface $response
54+
) : ResponseInterface {
55+
if ($debug) {
56+
$templateData['error'] = $e;
57+
}
58+
59+
$response->getBody()
60+
->write($renderer->render($this->template, $templateData));
61+
62+
return $response;
63+
}
64+
65+
private function prepareDefaultResponse(
66+
Throwable $e,
67+
bool $debug,
68+
ResponseInterface $response
69+
) : ResponseInterface {
70+
$message = 'An unexpected error occurred';
71+
72+
if ($debug) {
73+
$message .= "; stack trace:\n\n" . $this->prepareStackTrace($e);
74+
}
75+
76+
$response->getBody()->write($message);
77+
78+
return $response;
79+
}
80+
81+
/**
82+
* Prepares a stack trace to display.
83+
*/
84+
private function prepareStackTrace(Throwable $e) : string
85+
{
86+
$message = '';
87+
do {
88+
$message .= sprintf(
89+
$this->stackTraceTemplate,
90+
get_class($e),
91+
$e->getFile(),
92+
$e->getLine(),
93+
$e->getMessage(),
94+
$e->getTraceAsString()
95+
);
96+
} while ($e = $e->getPrevious());
97+
98+
return $message;
99+
}
100+
}

0 commit comments

Comments
 (0)