Passed
Pull Request — master (#77)
by Stefano
11:01
created

ExceptionRenderer   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 69
Duplicated Lines 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
eloc 26
c 4
b 0
f 0
dl 0
loc 69
rs 10
wmc 8

4 Methods

Rating   Name   Duplication   Size   Complexity  
A _getController() 0 8 2
A _outputMessageSafe() 0 22 2
A getHttpCode() 0 7 2
A _template() 0 8 2
1
<?php
2
declare(strict_types=1);
3
4
/**
5
 * BEdita, API-first content management framework
6
 * Copyright 2018 ChannelWeb Srl, Chialab Srl
7
 *
8
 * This file is part of BEdita: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published
10
 * by the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * See LICENSE.LGPL or <http://gnu.org/licenses/lgpl-3.0.html> for more details.
14
 */
15
16
namespace BEdita\WebTools\Error;
17
18
use BEdita\SDK\BEditaClientException;
19
use Cake\Controller\Controller;
20
use Cake\Error\Renderer\WebExceptionRenderer;
21
use Cake\Http\Response;
22
use Cake\Log\LogTrait;
23
24
/**
25
 * Custom exception renderer class.
26
 * Handle with templates 500 and 400 (for status code < 500).
27
 */
28
class ExceptionRenderer extends WebExceptionRenderer
29
{
30
    use LogTrait;
31
32
    /**
33
     * @inheritDoc
34
     */
35
    protected function _template(\Throwable $exception, string $method, int $code): string
36
    {
37
        $template = 'error500';
38
        if ($code < 500) {
39
            $template = 'error400';
40
        }
41
42
        return $this->template = $template;
43
    }
44
45
    /**
46
     * @inheritDoc
47
     */
48
    protected function _getController(): Controller
49
    {
50
        $controller = parent::_getController();
51
        if ($this->request->getHeaderLine('Accept') === 'application/json') {
52
            $controller->viewBuilder()->setClassName('Json');
53
        }
54
55
        return $controller;
56
    }
57
58
    /**
59
     * {@inheritDoc}
60
     *
61
     * Handle BEditaClientException.
62
     */
63
    protected function getHttpCode(\Throwable $exception): int
64
    {
65
        if ($exception instanceof BEditaClientException) {
66
            return $exception->getCode();
67
        }
68
69
        return parent::getHttpCode($exception);
70
    }
71
72
    /**
73
     * @inheritDoc
74
     */
75
    protected function _outputMessageSafe(string $template): Response
76
    {
77
        $builder = $this->controller->viewBuilder();
78
        $builder->setLayoutPath('')
79
            ->setTemplatePath('Error');
80
81
        // first try to use AppView class. Fallback to internal template on failure
82
        try {
83
            $view = $this->controller->createView();
84
            $body = $view->render($template, 'error');
85
        } catch (\Exception $e) {
86
            // first log the new exception to trace the new error too.
87
            $this->log($e->getMessage());
88
89
            $helpers = ['Form', 'Html'];
90
            $builder->setHelpers($helpers, false);
91
92
            $view = $this->controller->createView('View');
93
            $body = $view->render('BEdita/WebTools.' . $template, 'BEdita/WebTools.error');
94
        }
95
96
        return $this->controller->getResponse()->withStringBody($body)->withType('html');
97
    }
98
}
99