Hey Jakub,

On 20.11.2025 13:03:08, Jakub Zelenka wrote:

    My point here is that $code generally does not get used for our
    Exceptions. Whenever we need to attach extra information to an
    exception, we do it as extraneous properties. (That's what my
    example with ErrorException was about.)

    I.e. ignore the existence of $code (just assign zero).

    And add an extra property for the StreamError enum (which now
    needs no backing).

    class StreamException extends Exception {
        public __construct(
            public StreamError $error,
            public string $wrapperName,
            string $message = "",
            public string|null $param = "",
            ?Throwable $previous = null
        ) {
            parent::__construct($message, 0, $previous);
        }
    }

    Does this make more sense, described as code?


As I see what you mean now. I would prefer to use StreamError name for the class holding all the details including code, wrapper name, message and param as proposed by Jordi because this could be also passed to handler and retrieved from the stored errors. It just seems not right to use StreamException as a container without being thrown (is that done anywhere?) so I think separate class for handler and stored errors (or single last error) seems cleaner. Although StreamException would be then quite similar. I could pass StreamError there as a property but then it would duplicate the message so not sure.

In any case I think it's better to call that enum StreamErrorCode. I will still find a clean way to map it to the defines (STREAM_ERROR_CODE_* macros) because that's what I use internally to set code in the error. So not using int value for the exception code won't make that much difference from the implementation PoV.

I don't mind the name, whether you call it StreamError or StreamErrorCode. Or maybe call the class "StreamFailure" and the enum "StreamError"? Just a suggestion, I don't care too much about the actual names.

For the internal implementation, does it actually matter passing around an int value or a char pointer with the name? Which would allow you to directly pass it into the enum lookup. But yup, do whatever fits you best here :-)

(Ranty tangent: Umm, what's even the internal proper way to get an enum value? Manual zend_hash_find_ptr(CE_CONSTANTS_TABLE(ce), constant_name) including zend_update_class_constant()?! We ought to figure a way to create the internal enum case objects at compile time, then we could just reference them directly... Working with enums internally can be annoying and fetching *feels* slow (even if it's just a HashTable lookup).)


Bob

Reply via email to