Hi

On 3/29/23 16:31, Davey Shafik wrote:
The issue of contention here is that inheritance isn't the correct mechanism for reusing 
enum definitions to expand on them. What about allowing "use" syntax  like 
traits?

enum HttpErrors {
    case HTTP_STATUS_400;
    case HTTP_STATUS_401;
     …
}

I understand that this is just an example, but I'd like to note that using an enum for HTTP status codes would likely be a misuse. Valid HTTP status codes are all three-digit numbers in 1xx to 5xx and HTTP error codes are everything 4xx and 5xx. HTTP status code are specifically designed for you to be able to handle them generically based on the first digit, even if you don't know about the specific code.

enum ApiErrors {
    use HttpErrors;

    case JsonParserError;
    case GraphQLParserError;
}

Now you have ApiErrors::HTTP_STATUS_400 etc without ApiErrors being is-a 
HttpErrors.

Including all the cases of another enum is not unlikely to result in conflicts, because the enum name effectively acts as a namespace with regard to the enum cases.

Staying with the HttpErrors enum for sake of the example, you'd rather use `case Forbidden` instead of `case HTTP_STATUS_403`, because `HttpErrors::HTTP_STATUS_403` redundantly includes the 'HTTP'. Mark's example of DatabaseError would possibly also have a `case Forbidden` in case your database password is incorrect or in case you may not access the queried table or whatever.

Instead it would likely be preferable to get tagged unions (https://wiki.php.net/rfc/tagged_unions) and then nest the errors, like commonly done in Rust:

    enum ApiErrors {
        case HttpRequest(HttpErrors $httpError);
        case JsonParsing;
        case GraphQlParsing;
    }

And then `$foo = ApiErrors::HttpRequest(HttpErrors::Forbidden);`. The Exception equivalent would be leveraging the `$previous` value to provide the context.

Best regards
Tim Düsterhus

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php

Reply via email to