Fixed Race conditional when bookmarking can cause unexpected error

Affected version
2.1.3

Xon

Well-known member
If you bookmark the same item really quickly a bunch of errors are generated which don't make much sense;

Code:
LogicException: Cannot save with validation errors. Use validate() to ensure there are no errors. (First error: You have already bookmarked this content.)
src/XF/Service/ValidateAndSavableTrait.php:34
Aug 30, 2019 at 12:05 AM

Stack trace
#0 src/XF/ControllerPlugin/Bookmark.php(197): XF\Service\Bookmark\Creator->save()
#1 src/XF/ControllerPlugin/Bookmark.php(23): XF\ControllerPlugin\Bookmark->actionSaveBookmark(Object(SV\ReportCentreEssentials\XF\Entity\Post), '/posts/24029333...')
#2 src/XF/Pub/Controller/Post.php(358): XF\ControllerPlugin\Bookmark->actionBookmark(Object(SV\ReportCentreEssentials\XF\Entity\Post), '/posts/24029333...')
#3 src/XF/Mvc/Dispatcher.php(321): XF\Pub\Controller\Post->actionBookmark(Object(XF\Mvc\ParameterBag))
#4 src/XF/Mvc/Dispatcher.php(244): XF\Mvc\Dispatcher->dispatchClass('XF:Post', 'Bookmark', Object(XF\Mvc\RouteMatch), Object(SV\ReportCentreEssentials\XF\Pub\Controller\Post), NULL)
#5 src/XF/Mvc/Dispatcher.php(100): XF\Mvc\Dispatcher->dispatchFromMatch(Object(XF\Mvc\RouteMatch), Object(SV\ReportCentreEssentials\XF\Pub\Controller\Post), NULL)
#6 src/XF/Mvc/Dispatcher.php(50): XF\Mvc\Dispatcher->dispatchLoop(Object(XF\Mvc\RouteMatch))
#7 src/XF/App.php(2178): XF\Mvc\Dispatcher->run()
#8 src/XF.php(390): XF\App->run()
#9 index.php(20): XF::runApp('XF\\Pub\\App')
#10 {main}
Code:
XF\Db\DuplicateKeyException: MySQL query error [1062]: Duplicate entry '7997-post-24029333' for key 'user_id_content_type_content_id'
src/XF/Db/AbstractStatement.php:217
Aug 30, 2019 at 12:05 AM

Stack trace
INSERT  INTO `xf_bookmark_item` (`content_type`, `content_id`, `user_id`, `message`, `bookmark_id`, `bookmark_date`, `labels`) VALUES (?, ?, ?, ?, ?, ?, ?)
------------

#0 src/XF/Db/Mysqli/Statement.php(196): XF\Db\AbstractStatement->getException('MySQL query err...', 1062, '23000')
#1 src/XF/Db/Mysqli/Statement.php(77): XF\Db\Mysqli\Statement->getException('MySQL query err...', 1062, '23000')
#2 src/XF/Db/AbstractAdapter.php(94): XF\Db\Mysqli\Statement->execute()
#3 src/XF/Db/AbstractAdapter.php(218): XF\Db\AbstractAdapter->query('INSERT INTO `x...', Array)
#4 src/XF/Mvc/Entity/Entity.php(1452): XF\Db\AbstractAdapter->insert('xf_bookmark_ite...', Array, false)
#5 src/XF/Mvc/Entity/Entity.php(1184): XF\Mvc\Entity\Entity->_saveToSource()
#6 src/XF/Service/Bookmark/Creator.php(99): XF\Mvc\Entity\Entity->save()
#7 src/XF/Service/ValidateAndSavableTrait.php(40): XF\Service\Bookmark\Creator->_save()
#8 src/XF/ControllerPlugin/Bookmark.php(197): XF\Service\Bookmark\Creator->save()
#9 src/XF/ControllerPlugin/Bookmark.php(23): XF\ControllerPlugin\Bookmark->actionSaveBookmark(Object(SV\ReportCentreEssentials\XF\Entity\Post), '/posts/24029333...')
#10 src/XF/Pub/Controller/Post.php(358): XF\ControllerPlugin\Bookmark->actionBookmark(Object(SV\ReportCentreEssentials\XF\Entity\Post), '/posts/24029333...')
#11 src/XF/Mvc/Dispatcher.php(321): XF\Pub\Controller\Post->actionBookmark(Object(XF\Mvc\ParameterBag))
#12 src/XF/Mvc/Dispatcher.php(244): XF\Mvc\Dispatcher->dispatchClass('XF:Post', 'Bookmark', Object(XF\Mvc\RouteMatch), Object(SV\ReportCentreEssentials\XF\Pub\Controller\Post), NULL)
#13 src/XF/Mvc/Dispatcher.php(100): XF\Mvc\Dispatcher->dispatchFromMatch(Object(XF\Mvc\RouteMatch), Object(SV\ReportCentreEssentials\XF\Pub\Controller\Post), NULL)
#14 src/XF/Mvc/Dispatcher.php(50): XF\Mvc\Dispatcher->dispatchLoop(Object(XF\Mvc\RouteMatch))
#15 src/XF/App.php(2178): XF\Mvc\Dispatcher->run()
#16 src/XF.php(390): XF\App->run()
#17 index.php(20): XF::runApp('XF\\Pub\\App')
#18 {main}
 

XF Bug Bot

XenForo bug fixer bot
Staff member
Thank you for reporting this issue. It has now been resolved and we are aiming to include it in a future XF release (2.1.5).

Change log:
Gracefully handle a race condition when inserting bookmarks.
Any changes made as a result of this issue being resolved may not be rolled out here until later.
 
Top