You probably should check for Traversable objects in general using instanceof_function(Z_OBJCE_P(data), zend_ce_traversable).
If the type of the retval is IS_UNDEF after calling a user function, this means the function threw an exception.
Aside: you can just use Z_TYPE(retval) instead of Z_TYPE_P(&retval)