Not a bug Replier can only add posts at the end of a thread

Nirjonadda

Well-known member
Affected version
2.0.1
I am getting server error log but does this bug from xenforo?

Code:
LogicException: Replier can only add posts at the end of a thread src/XF/Service/Thread/Replier.php:176

Generated by: prinanad Jan 3, 2018 at 2:55 PM

Stack trace

#0 src/XF/Service/Thread/Replier.php(159): XF\Service\Thread\Replier->setPostPosition(Array)
#1 src/XF/Service/ValidateAndSavableTrait.php(40): XF\Service\Thread\Replier->_save()
#2 src/XF/Pub/Controller/Thread.php(431): XF\Service\Thread\Replier->save()
#3 src/XF/Mvc/Dispatcher.php(249): XF\Pub\Controller\Thread->actionAddReply(Object(XF\Mvc\ParameterBag))
#4 src/XF/Mvc/Dispatcher.php(88): XF\Mvc\Dispatcher->dispatchClass('XF:Thread', 'AddReply', 'json', Object(XF\Mvc\ParameterBag), 'forums', Object(NF\TrashCan\XF\Pub\Controller\Thread), NULL)
#5 src/XF/Mvc/Dispatcher.php(41): XF\Mvc\Dispatcher->dispatchLoop(Object(XF\Mvc\RouteMatch))
#6 src/XF/App.php(1880): XF\Mvc\Dispatcher->run()
#7 src/XF.php(328): XF\App->run()
#8 index.php(13): XF::runApp('XF\\Pub\\App')
#9 {main}

Request state

array(4) {
  ["url"] => string(46) "/threads/recent-celebrity-hunts.6472/add-reply"
  ["referrer"] => string(72) "/recent-celebrity-hunts.6472/page-2848"
  ["_GET"] => array(0) {
  }
  ["_POST"] => array(9) {
    ["message_html"] => string(216) "<p><br>URL removed</p>"
    ["attachment_hash"] => string(32) "12b8ac8ee02b449b4c62a4a5df9ba2d8"
    ["attachment_hash_combined"] => string(86) "{"type":"post","context":{"thread_id":6472},"hash":"12b8ac8ee02b449b4c62a4a5df9ba2d8"}"
    ["last_date"] => string(10) "1514969694"
    ["last_known_date"] => string(10) "1514950552"
    ["_xfToken"] => string(8) "********"
    ["_xfRequestUri"] => string(46) "/threads/recent-celebrity-hunts.6472/page-2848"
    ["_xfWithData"] => string(1) "1"
    ["_xfResponseType"] => string(4) "json"
  }
}
 
We have started getting that error recently on XF 2.1.10P2 and our servers are all syncing time.

Are you sure? I put in a ton of work to build the case to my service provider that they had a time problem
with one/some of their nodes.

have you seen posts in the future? where the time says "in a moment" or "in a minute" ?
this happens when served by a node that is "behind" OR the last post was made by a node that is "ahead"

I'd recommend creating a small php script which you can run when getting this error to compare device time(ie your tablet) to server time
to see if they are different - just display server time, and screen shot it with the device time for evidence.
Hoping that they are session caching, and routing device request to the same place.

While debugging, I added code to force-post by taking the last post time, adding 1 second.
at least the community didn't get the error, even if they thought their posts were clairvoyant.

if the is_admin (can't remember if this is correct) is set, this was added to the footer.
It can be run stand-alone - it grabs time a couple different ways - as i was grasping for answers.


PHP:
<?php
        date_default_timezone_set('America/New_York');
        echo '<div> <p style="color:red">';
        $timestamp = exec("TZ='America/New_York' /bin/date +%s");
        // echo $_SERVER['REQUEST_TIME'] . ", " . time() . ", $timestamp" .  date(",  H:i:s </p></div>");
        echo time() . ", $timestamp" .  date(",  H:i:s </p></div>");
?>
 
Last edited:
Not that I'm aware, but the absence of complaint doesn't mean that users aren't being negatively impacted. We want our users to have a good experience.

Anywhere from a thousand to eight thousand simultaneous users. But the error doesn't seem to correlate with instantaneous aggregate user activity.
 
Not that I'm aware, but the absence of complaint doesn't mean that users aren't being negatively impacted. We want our users to have a good experience.

Anywhere from a thousand to eight thousand simultaneous users. But the error doesn't seem to correlate with instantaneous aggregate user activity.

Interesting, it has to be a race condition.
two users posting to the same thread at the same time - one user is getting an alert that says 'oops something went wrong' -
they hit submit again, and the post goes through.

"at the same time" means the post throwing the exception is probably 1 second behind - according to the php call to time() ,
which really means a clock border condition. It does not use database time - so no need to look there.

Xenforo enforces the rule about 'end of thread' - but interestingly enough, it does not care if the times are equal!
This is in function setPostPosition() - as the error notes.

It might open a box of worms, but the code could test for 1 second behind,
if true, make it equal, and push the post. I believe the record is open for update in the DB, so it should have a lock.

Totally untested - but while i was having the problem, this is similar to what i did to improve user experience.

PHP:
protected function setPostPosition(array $threadInfo)
        {
                $post = $this->post;

                if ($post->post_date < $threadInfo['last_post_date'])
                {
//* New!
                        if (($post->post_date + 1) == threadInfo['last_post_date'] )
                        {
                                $post->set('post_date', threadInfo['last_post_date'], ['forceSet' => true]);
                        } else {
                                throw new \LogicException("Replier can only add posts at the end of a thread");
                        }
//End New
/*/
// Old
                                 throw new \LogicException("Replier can only add posts at the end of a thread");
//End Old */
                }

                if ($post->message_state == 'visible')
                {
                        $position = $threadInfo['reply_count'] + 1;
                }
                else
                {
                        $position = $threadInfo['reply_count'];
                }


                $post->set('position', $position, ['forceSet' => true]);
        }
 
Last edited:
Top Bottom