You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
wp_set_presence() returns false when recording is off, the table is missing, $date_gmt is malformed, $expires_in is unusable, or the query fails. A caller can't tell which, so it can't tell "this site doesn't record presence" from "something broke".
Return a WP_Error with its own code for each.
To decide
Callers today check false. Either:
A $wp_error flag, like wp_insert_post(): false stays the default and true gets the WP_Error. Nothing breaks.
Always a WP_Error, and callers switch to is_wp_error(). Cleaner, but every false === wp_set_presence( … ) check breaks, including gutenberg-sync-engines'.
The $wp_error flag fits naturally into the $args array if that lands first.
Tasks
Pick one
One error code per rejection, listed in the docblock and README
I'd go with the $wp_error flag, defaulting to false, like wp_insert_post().
Always returning WP_Error would break callers quietly, not loudly: a WP_Error is truthy, so every if ( ! wp_set_presence( … ) ) here (REST, WP-CLI, wp_presence_exchange()) and in gutenberg-sync-engines would read a refusal as success, and a storage class returning it from Gutenberg's WP_Sync_Storage::set_awareness_state(): bool would throw a TypeError. Gutenberg's own sync server keeps storage returning bool and builds the WP_Error at its REST boundary, so the same split fits here.
The REST controller and WP-CLI already check recording (501) and the table (503) before writing, so the generic rest_presence_failed 500 is left for a failed database write; the flag's job is mainly for callers outside this plugin, which today can't tell those apart.
#792 is a draft of this. Once #789 lands I'll rebase it so the flag is only a 'wp_error' key in $args. Happy to take it if you assign me.
Decided: the $wp_error flag, as a 'wp_error' key in $args that defaults to false, for the reasons you gave; with it on, wp_presence_exchange() returns the WP_Error in place of the room when its write is refused. #789 is merged, so #792 is ready to rebase that way, and if it lands before the 0.17.0 release (#790) it ships together with $args. Thanks for the careful write-up!
Activity
huzaifaalmesbah commentedon Oct 8, 2026
I'd go with the
$wp_errorflag, defaulting tofalse, likewp_insert_post().Always returning
WP_Errorwould break callers quietly, not loudly: aWP_Erroris truthy, so everyif ( ! wp_set_presence( … ) )here (REST, WP-CLI,wp_presence_exchange()) and in gutenberg-sync-engines would read a refusal as success, and a storage class returning it from Gutenberg'sWP_Sync_Storage::set_awareness_state(): boolwould throw aTypeError. Gutenberg's own sync server keeps storage returningbooland builds theWP_Errorat its REST boundary, so the same split fits here.The REST controller and WP-CLI already check recording (501) and the table (503) before writing, so the generic
rest_presence_failed500 is left for a failed database write; the flag's job is mainly for callers outside this plugin, which today can't tell those apart.#792 is a draft of this. Once #789 lands I'll rebase it so the flag is only a
'wp_error'key in$args. Happy to take it if you assign me.josephfusco commentedon Oct 8, 2026
Decided: the
$wp_errorflag, as a'wp_error'key in$argsthat defaults tofalse, for the reasons you gave; with it on,wp_presence_exchange()returns theWP_Errorin place of the room when its write is refused. #789 is merged, so #792 is ready to rebase that way, and if it lands before the 0.17.0 release (#790) it ships together with$args. Thanks for the careful write-up!feat: let a presence write say why it was refused
feat: return WP_Error with specific refusal codes when presence write…