Skip to content

ExceptionApiProblem does not handle exceptions that return a non-numeric status code #14

@judgej

Description

@judgej

Bug Report

Summary

Some exceptions return a code getCode() - that are non-numeric, but a string instead. For example an Illuminate\Database\QueryException in a Laravel application had a code "42S02" (note the "S" in the middle). Passing this into the Phpro\ApiProblem\Http\ExceptionApiProblem for rendering results in a further exception being thrown:

Phpro\ApiProblem\Http\HttpApiProblem::__construct(): Argument #1 ($statusCode) must be of type int, string given, called in /.../vendor/phpro/api-problem/src/Http/ExceptionApiProblem.php on line 26 {"exception":"[object] (TypeError(code: 0): Phpro\ApiProblem\Http\HttpApiProblem::__construct(): Argument #1 ($statusCode) must be of type int, string given, called in /.../vendor/phpro/api-problem/src/Http/ExceptionApiProblem.php on line 26 at /.../vendor/phpro/api-problem/src/Http/HttpApiProblem.php:60)

Current behaviour

How to reproduce

This is hard to reproduce outside of Laravel. You cannot create a Illuminate\Database\QueryException exception with a non-numeric code directly, but the framework can. Within laravel, accessing a table that does not exist through the database builder generates an SQL error with details:

+errorInfo: array:3 [
      0 => "42S02"
      1 => 1146
      2 => "Table 'print_trail_core.jobs' doesn't exist"
    ]

which is passed into a PDOException exception, which in turn is passed into an Illuminate\Database\QueryException exception. Fetching the code for that gives "42S02" and that is a problem when that exception is passed to Phpro\ApiProblem\Http\ExceptionApiProblem.

The constructor checks if the code is in the range 400 to 599 and uses it directly if it is, and (bizarrely) it is:

>>> $exceptionCode = "42S02"
=> "42S02"
>>> $statusCode = $exceptionCode >= 400 && $exceptionCode <= 599 ? $exceptionCode : 500
=> "42S02"

If I cast the status code to an int, then it comes out as 42 (again, not sure why - it should be a 500 surely?) but it does not throw a second exception.

Expected behaviour

An exception passed to Phpro\ApiProblem\Http\ExceptionApiProblem that returns a non-numeric getStatus() (and they do exist) should result in a code of 500, and not throw another exception complaining about the non-numeric status code that it tries to use to pass to the parent constructor (class Phpro\ApiProblem\Http\HttpApiProblem).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions