Merge branch 'fix-api-404' into development

This commit is contained in:
Dan Brown 2023-06-15 17:08:51 +01:00
commit ec775aec02
No known key found for this signature in database
GPG Key ID: 46D9F943C24A2EF9
4 changed files with 60 additions and 23 deletions

View File

@ -9,7 +9,7 @@ use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException; use Illuminate\Validation\ValidationException;
use Symfony\Component\HttpKernel\Exception\HttpException; use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Throwable; use Throwable;
class Handler extends ExceptionHandler class Handler extends ExceptionHandler
@ -82,7 +82,7 @@ class Handler extends ExceptionHandler
$code = 500; $code = 500;
$headers = []; $headers = [];
if ($e instanceof HttpException) { if ($e instanceof HttpExceptionInterface) {
$code = $e->getStatusCode(); $code = $e->getStatusCode();
$headers = $e->getHeaders(); $headers = $e->getHeaders();
} }
@ -103,10 +103,6 @@ class Handler extends ExceptionHandler
$code = $e->status; $code = $e->status;
} }
if (method_exists($e, 'getStatus')) {
$code = $e->getStatus();
}
$responseData['error']['code'] = $code; $responseData['error']['code'] = $code;
return new JsonResponse($responseData, $code, $headers); return new JsonResponse($responseData, $code, $headers);

View File

@ -4,29 +4,39 @@ namespace BookStack\Exceptions;
use Exception; use Exception;
use Illuminate\Contracts\Support\Responsable; use Illuminate\Contracts\Support\Responsable;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
class NotifyException extends Exception implements Responsable class NotifyException extends Exception implements Responsable, HttpExceptionInterface
{ {
public $message; public $message;
public $redirectLocation; public string $redirectLocation;
protected $status; protected int $status;
public function __construct(string $message, string $redirectLocation = '/', int $status = 500) public function __construct(string $message, string $redirectLocation = '/', int $status = 500)
{ {
$this->message = $message; $this->message = $message;
$this->redirectLocation = $redirectLocation; $this->redirectLocation = $redirectLocation;
$this->status = $status; $this->status = $status;
parent::__construct(); parent::__construct();
} }
/** /**
* Get the desired status code for this exception. * Get the desired HTTP status code for this exception.
*/ */
public function getStatus(): int public function getStatusCode(): int
{ {
return $this->status; return $this->status;
} }
/**
* Get the desired HTTP headers for this exception.
*/
public function getHeaders(): array
{
return [];
}
/** /**
* Send the response for this type of exception. * Send the response for this type of exception.
* *
@ -38,7 +48,7 @@ class NotifyException extends Exception implements Responsable
// Front-end JSON handling. API-side handling managed via handler. // Front-end JSON handling. API-side handling managed via handler.
if ($request->wantsJson()) { if ($request->wantsJson()) {
return response()->json(['error' => $message], 403); return response()->json(['error' => $message], $this->getStatusCode());
} }
if (!empty($message)) { if (!empty($message)) {

View File

@ -4,18 +4,12 @@ namespace BookStack\Exceptions;
use Exception; use Exception;
use Illuminate\Contracts\Support\Responsable; use Illuminate\Contracts\Support\Responsable;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
class PrettyException extends Exception implements Responsable class PrettyException extends Exception implements Responsable, HttpExceptionInterface
{ {
/** protected ?string $subtitle = null;
* @var ?string protected ?string $details = null;
*/
protected $subtitle = null;
/**
* @var ?string
*/
protected $details = null;
/** /**
* Render a response for when this exception occurs. * Render a response for when this exception occurs.
@ -24,7 +18,7 @@ class PrettyException extends Exception implements Responsable
*/ */
public function toResponse($request) public function toResponse($request)
{ {
$code = ($this->getCode() === 0) ? 500 : $this->getCode(); $code = $this->getStatusCode();
return response()->view('errors.' . $code, [ return response()->view('errors.' . $code, [
'message' => $this->getMessage(), 'message' => $this->getMessage(),
@ -46,4 +40,20 @@ class PrettyException extends Exception implements Responsable
return $this; return $this;
} }
/**
* Get the desired HTTP status code for this exception.
*/
public function getStatusCode(): int
{
return ($this->getCode() === 0) ? 500 : $this->getCode();
}
/**
* Get the desired HTTP headers for this exception.
*/
public function getHeaders(): array
{
return [];
}
} }

View File

@ -159,6 +159,27 @@ class PagesApiTest extends TestCase
$this->assertStringContainsString('testing', $html); $this->assertStringContainsString('testing', $html);
} }
public function test_read_endpoint_returns_not_found()
{
$this->actingAsApiEditor();
// get an id that is not used
$id = Page::orderBy('id', 'desc')->first()->id + 1;
$this->assertNull(Page::find($id));
$resp = $this->getJson($this->baseEndpoint . "/$id");
$resp->assertNotFound();
$this->assertNull($resp->json('id'));
$resp->assertJsonIsObject('error');
$resp->assertJsonStructure([
'error' => [
'code',
'message',
],
]);
$this->assertSame(404, $resp->json('error')['code']);
}
public function test_update_endpoint() public function test_update_endpoint()
{ {
$this->actingAsApiEditor(); $this->actingAsApiEditor();