1616use Phalcon \Http \ResponseInterface ;
1717use Phalcon \Messages \MessageInterface ;
1818use Phalcon \Mvc \Dispatcher ;
19+ use Countable ;
1920use PhalconKit \Http \StatusCode as HttpStatusCode ;
2021use PhalconKit \Mvc \Controller \Traits \Abstracts \AbstractDebug ;
2122use PhalconKit \Mvc \Controller \Traits \Abstracts \AbstractInjectable ;
@@ -184,7 +185,7 @@ protected function getRestActionFailureStatusCode(
184185 int $ emptyStatusCode = 400 ,
185186 int $ defaultStatusCode = 422
186187 ): int {
187- if (empty ($ messages )) {
188+ if (! $ this -> hasRestActionMessages ($ messages )) {
188189 return $ emptyStatusCode ;
189190 }
190191
@@ -198,6 +199,35 @@ protected function getRestActionFailureStatusCode(
198199 return $ defaultStatusCode ;
199200 }
200201
202+ /**
203+ * Determine whether a REST action failure carried any message payload.
204+ *
205+ * PHP objects are never empty for `empty()`, even when they implement
206+ * `Countable` and contain zero messages. Phalcon validation returns
207+ * `Phalcon\Messages\Messages`, so status resolution must check the
208+ * collection count instead of relying on PHP object truthiness.
209+ */
210+ protected function hasRestActionMessages (mixed $ messages ): bool
211+ {
212+ if ($ messages instanceof Countable) {
213+ return count ($ messages ) > 0 ;
214+ }
215+
216+ if (is_array ($ messages )) {
217+ return count ($ messages ) > 0 ;
218+ }
219+
220+ if ($ messages instanceof \Traversable) {
221+ foreach ($ messages as $ _message ) {
222+ return true ;
223+ }
224+
225+ return false ;
226+ }
227+
228+ return (bool ) $ messages ;
229+ }
230+
201231 /**
202232 * Return a normalized REST error response for an action failure.
203233 *
0 commit comments