Skip to content

Commit 4c0fdca

Browse files
committed
Merge branch 'release/1.0.0-beta.4' into main
2 parents a00178a + 2b454b2 commit 4c0fdca

File tree

5 files changed

+74
-177
lines changed

5 files changed

+74
-177
lines changed

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,21 @@
33
All notable changes to this project will be documented in this file. This project adheres to
44
[Semantic Versioning](http://semver.org/) and [this changelog format](http://keepachangelog.com/).
55

6+
## [1.0.0-beta.4] - 2021-07-10
7+
8+
### Added
9+
10+
- When converting an exception to the default JSON:API error, detailed exception information will now be added to the
11+
JSON:API error if the application is running in debug mode. The exception code will be added to the `code` member, and
12+
the actual exception message to the `detail` member. The `meta` member will contain the exception class, file, line
13+
number and stack trace.
14+
15+
### Removed
16+
17+
- This package no longer handles the `UnexpectedDocumentException` from the `laravel-json-api/spec` package. The
18+
exception has been removed from that package, and it instead throws a `JsonApiException` if it cannot decode a JSON
19+
string.
20+
621
## [1.0.0-beta.3] - 2021-04-26
722

823
### Added

composer.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,11 @@
2727
"ext-json": "*",
2828
"illuminate/contracts": "^8.0",
2929
"illuminate/pipeline": "^8.0",
30-
"laravel-json-api/core": "^1.0.0-beta.1"
30+
"laravel-json-api/core": "^1.0.0-beta.1",
31+
"laravel-json-api/validation": "^1.0.0-beta.1"
3132
},
3233
"require-dev": {
33-
"laravel-json-api/spec": "^1.0.0-beta.1",
3434
"laravel-json-api/testing": "^1.0.0-beta.1",
35-
"laravel-json-api/validation": "^1.0.0-beta.1",
3635
"orchestra/testbench": "^6.9",
3736
"phpunit/phpunit": "^9.5"
3837
},

src/ExceptionParser.php

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
use Illuminate\Http\Request;
2525
use Illuminate\Http\Response;
2626
use Illuminate\Pipeline\Pipeline;
27+
use Illuminate\Support\Arr;
2728
use Illuminate\Support\Collection;
2829
use Illuminate\Support\Enumerable;
2930
use LaravelJsonApi\Core\Document\Error;
@@ -61,7 +62,6 @@ final class ExceptionParser
6162
Pipes\AuthenticationExceptionHandler::class,
6263
Pipes\HttpExceptionHandler::class,
6364
Pipes\RequestExceptionHandler::class,
64-
Pipes\UnexpectedDocumentExceptionHandler::class,
6565
Pipes\ValidationExceptionHandler::class,
6666
];
6767

@@ -210,7 +210,7 @@ public function parse(Throwable $ex, $request): ErrorResponse
210210
->send($ex)
211211
->through($this->pipes)
212212
->via('handle')
213-
->then(fn() => new ErrorResponse($this->getDefaultError()));
213+
->then(fn(Throwable $ex) => new ErrorResponse($this->getDefaultError($ex)));
214214
}
215215

216216
/**
@@ -292,17 +292,48 @@ private function mustAccept(Throwable $ex, $request): bool
292292
/**
293293
* Get the default JSON API error.
294294
*
295+
* @param Throwable $ex
295296
* @return Error
296297
*/
297-
private function getDefaultError(): Error
298+
private function getDefaultError(Throwable $ex): Error
298299
{
299300
if ($this->default) {
300301
return $this->default;
301302
}
302303

303-
return Error::make()
304+
$error = Error::make()
304305
->setStatus(500)
305306
->setTitle(__(Response::$statusTexts[500]));
307+
308+
if (config('app.debug')) {
309+
$error->setCode($ex->getCode())
310+
->setDetail($ex->getMessage())
311+
->setMeta($this->convertExceptionToMeta($ex));
312+
}
313+
314+
return $error;
315+
}
316+
317+
/**
318+
* Convert the provided exception to error meta.
319+
*
320+
* In this method we mirror the information that Laravel's exception handler
321+
* puts into its JSON representation of an exception when in debug mode.
322+
*
323+
* @param Throwable $ex
324+
* @return array
325+
* @see \Illuminate\Foundation\Exceptions\Handler::convertExceptionToArray()
326+
*/
327+
private function convertExceptionToMeta(Throwable $ex): array
328+
{
329+
return [
330+
'exception' => get_class($ex),
331+
'file' => $ex->getFile(),
332+
'line' => $ex->getLine(),
333+
'trace' => Collection::make($ex->getTrace())
334+
->map(fn($trace) => Arr::except($trace, ['args']))
335+
->all(),
336+
];
306337
}
307338

308339
}

src/Pipes/UnexpectedDocumentExceptionHandler.php

Lines changed: 0 additions & 89 deletions
This file was deleted.

tests/Integration/ExceptionsTest.php

Lines changed: 22 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,12 @@
2525
use Illuminate\Contracts\Validation\Validator;
2626
use Illuminate\Foundation\Http\Exceptions\MaintenanceModeException;
2727
use Illuminate\Session\TokenMismatchException;
28+
use Illuminate\Support\Arr;
29+
use Illuminate\Support\Collection;
2830
use Illuminate\Support\Facades\Route;
2931
use Illuminate\Support\MessageBag;
3032
use Illuminate\Validation\ValidationException;
3133
use LaravelJsonApi\Core\Exceptions\JsonApiException;
32-
use LaravelJsonApi\Spec\UnexpectedDocumentException;
3334
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
3435
use Symfony\Component\HttpKernel\Exception\HttpException;
3536
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
@@ -472,64 +473,17 @@ public function testValidationException(): void
472473
->assertExactJson($expected);
473474
}
474475

475-
public function testUnexpectedDocument(): void
476+
public function testDefaultExceptionWithoutDebug(): void
476477
{
477-
$this->ex = new UnexpectedDocumentException('That document is wrong.');
478+
config()->set('app.debug', false);
478479

479-
$expected = [
480-
'errors' => [
481-
[
482-
'detail' => 'That document is wrong.',
483-
'title' => 'Invalid JSON',
484-
'status' => '400',
485-
],
486-
],
487-
'jsonapi' => [
488-
'version' => '1.0',
489-
],
490-
];
491-
492-
$this->get('/test', ['Accept' => 'application/vnd.api+json'])
493-
->assertStatus(400)
494-
->assertHeader('Content-Type', 'application/vnd.api+json')
495-
->assertExactJson($expected);
496-
}
497-
498-
public function testUnexpectedDocumentWithoutMessage(): void
499-
{
500-
$this->ex = new UnexpectedDocumentException();
501-
502-
$expected = [
503-
'errors' => [
504-
[
505-
'title' => 'Invalid JSON',
506-
'status' => '400',
507-
],
508-
],
509-
'jsonapi' => [
510-
'version' => '1.0',
511-
],
512-
];
513-
514-
$this->get('/test', ['Accept' => 'application/vnd.api+json'])
515-
->assertStatus(400)
516-
->assertHeader('Content-Type', 'application/vnd.api+json')
517-
->assertExactJson($expected);
518-
}
519-
520-
public function testUnexpectedDocumentWithJsonException(): void
521-
{
522-
$json = new \JsonException('Bad format.', 4);
523-
524-
$this->ex = new UnexpectedDocumentException('That document is wrong.', 0, $json);
480+
$this->ex = new \Exception('Boom.');
525481

526482
$expected = [
527483
'errors' => [
528484
[
529-
'code' => '4',
530-
'detail' => 'Bad format.',
531-
'title' => 'Invalid JSON',
532-
'status' => '400',
485+
'title' => 'Internal Server Error',
486+
'status' => '500',
533487
],
534488
],
535489
'jsonapi' => [
@@ -538,45 +492,32 @@ public function testUnexpectedDocumentWithJsonException(): void
538492
];
539493

540494
$this->get('/test', ['Accept' => 'application/vnd.api+json'])
541-
->assertStatus(400)
495+
->assertStatus(500)
542496
->assertHeader('Content-Type', 'application/vnd.api+json')
543497
->assertExactJson($expected);
544498
}
545499

546-
public function testUnexpectedDocumentWithJsonExceptionWithoutMessage(): void
500+
public function testDefaultExceptionWithDebug(): void
547501
{
548-
$json = new \JsonException('', 4);
502+
config()->set('app.debug', true);
549503

550-
$this->ex = new UnexpectedDocumentException('That document is wrong.', 0, $json);
504+
$this->ex = $ex = new \LogicException('Boom.', 99);
551505

552506
$expected = [
553507
'errors' => [
554508
[
555-
'code' => '4',
556-
'title' => 'Invalid JSON',
557-
'status' => '400',
558-
],
559-
],
560-
'jsonapi' => [
561-
'version' => '1.0',
562-
],
563-
];
564-
565-
$this->get('/test', ['Accept' => 'application/vnd.api+json'])
566-
->assertStatus(400)
567-
->assertHeader('Content-Type', 'application/vnd.api+json')
568-
->assertExactJson($expected);
569-
}
570-
571-
public function testGenericException(): void
572-
{
573-
$this->ex = new \Exception('Boom.');
574-
575-
$expected = [
576-
'errors' => [
577-
[
578-
'title' => 'Internal Server Error',
509+
'code' => (string) $ex->getCode(),
510+
'detail' => $ex->getMessage(),
511+
'meta' => [
512+
'exception' => get_class($ex),
513+
'file' => $ex->getFile(),
514+
'line' => $ex->getLine(),
515+
'trace' => Collection::make($ex->getTrace())
516+
->map(fn($trace) => Arr::except($trace, ['args']))
517+
->all(),
518+
],
579519
'status' => '500',
520+
'title' => 'Internal Server Error',
580521
],
581522
],
582523
'jsonapi' => [

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy