-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathAbstractHandler.php
More file actions
231 lines (202 loc) · 6.51 KB
/
Copy pathAbstractHandler.php
File metadata and controls
231 lines (202 loc) · 6.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
<?php
namespace SMartins\Exceptions\Handlers;
use Throwable;
use Exception;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;
use InvalidArgumentException;
use SMartins\Exceptions\JsonApi\Response as JsonApiResponse;
use SMartins\Exceptions\Response\ErrorHandledCollectionInterface;
use SMartins\Exceptions\Response\ErrorHandledInterface;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
abstract class AbstractHandler
{
/**
* The exception thrown.
*
* @var \Exception
*/
protected $exception;
/**
* An array where the key is the class exception and the value is the handler
* class that will treat the exception.
*
* @var array
*/
protected $exceptionHandlers = [];
/**
* An internal array where the key is the exception class and the value is
* the handler class that will treat the exception.
*
* @var array
*/
protected $internalExceptionHandlers = [
Exception::class => Handler::class,
ModelNotFoundException::class => ModelNotFoundHandler::class,
AuthenticationException::class => AuthenticationHandler::class,
ValidationException::class => ValidationHandler::class,
BadRequestHttpException::class => BadRequestHttpHandler::class,
AuthorizationException::class => AuthorizationHandler::class,
NotFoundHttpException::class => NotFoundHttpHandler::class,
'Laravel\Passport\Exceptions\MissingScopeException' => MissingScopeHandler::class,
'League\OAuth2\Server\Exception\OAuthServerException' => OAuthServerHandler::class,
];
/**
* Create instance using the Exception to be handled.
*
* @param Exception $e
*/
public function __construct(Throwable $e)
{
$this->exception = $e;
}
/**
* Handle with an exception according to specific definitions. Returns one
* or more errors using the exception from $exceptions attribute.
*
* @return ErrorHandledInterface|ErrorHandledCollectionInterface
*/
abstract public function handle();
/**
* Get error code. If code is empty from config file based on type.
*
* @param string $type Code type from config file
* @return int
*/
public function getCode($type = 'default')
{
if (empty($code = $this->exception->getCode())) {
return config('json-exception-handler.codes.'.$type);
}
return $code;
}
/**
* Return response with handled exception.
*
* @return \SMartins\Exceptions\Response\AbstractResponse
* @throws \SMartins\Exceptions\Response\InvalidContentException
*/
public function handleException()
{
$handler = $this->getExceptionHandler();
$errors = $this->validatedHandledException($handler->handle());
$responseHandler = $this->getResponseHandler();
return new $responseHandler($errors);
}
/**
* Validate response from handle method of handler class.
*
* @param ErrorHandledInterface|ErrorHandledCollectionInterface
* @return ErrorHandledCollectionInterface
*
* @throws \SMartins\Exceptions\Response\InvalidContentException
*/
public function validatedHandledException($error)
{
if ($error instanceof ErrorHandledCollectionInterface) {
return $error->validatedContent(ErrorHandledInterface::class);
} elseif ($error instanceof ErrorHandledInterface) {
return $error->toCollection()->setStatusCode($error->getStatus());
}
throw new InvalidArgumentException('The errors must be an instance of ['.ErrorHandledInterface::class.'] or ['.ErrorHandledCollectionInterface::class.'].');
}
/**
* Get the class the will handle the Exception from exceptionHandlers attributes.
*
* @return mixed
*/
public function getExceptionHandler()
{
$handlers = $this->getConfiguredHandlers();
$handler = isset($handlers[get_class($this->exception)])
? $handlers[get_class($this->exception)]
: $this->getDefaultHandler();
return new $handler($this->exception);
}
/**
* Get exception handlers from internal and set on App\Exceptions\Handler.php.
*
* @return array
*/
public function getConfiguredHandlers()
{
return array_merge($this->internalExceptionHandlers, $this->exceptionHandlers);
}
/**
* Get default pointer using file and line of exception.
*
* @return string
*/
public function getDefaultPointer()
{
return '';
}
/**
* Get default title from exception.
*
* @return string
*/
public function getDefaultTitle()
{
return Str::snake(class_basename($this->exception));
}
/**
* Get default http code. Check if exception has getStatusCode() methods.
* If not get from config file.
*
* @return int
*/
public function getStatusCode()
{
if (method_exists($this->exception, 'getStatusCode')) {
return $this->exception->getStatusCode();
}
return config('json-exception-handler.http_code');
}
/**
* The default handler to handle not treated exceptions.
*
* @return \SMartins\Exceptions\Handlers\Handler
*/
public function getDefaultHandler()
{
return new Handler($this->exception);
}
/**
* Get default response handler of the if any response handler was defined
* on config file.
*
* @return string
*/
public function getDefaultResponseHandler()
{
return JsonApiResponse::class;
}
/**
* Get the response class that will handle the json response.
*
* @todo Check if the response_handler on config is an instance of
* \SMartins\Exceptions\Response\AbstractResponse
* @return string
*/
public function getResponseHandler()
{
$response = config('json-exception-handler.response_handler');
return $response ?? $this->getDefaultResponseHandler();
}
/**
* Set exception handlers.
*
* @param array $handlers
* @return AbstractHandler
*/
public function setExceptionHandlers(array $handlers)
{
$this->exceptionHandlers = $handlers;
return $this;
}
}