I've got a block that relies on a fairly flaky third party service to get data to render so, when it does encounter a problem, I'd like to display an error message, rather than throw an exception and not render the page.
Easy enough to do until you come to block/page caching. The data has a long lifetime so, when found, it's fine to cache everything. When it isn't, though, the page is cached with the error message in place. As such, I need to tell the CMS not to save the block or page output to the cache.
Example code (within block controller):
public function view() {
try {
$this->set ('data', $this->getData());
} catch (\Exception $e) {
\Log::addError ('Blockname Error: '.$e->getMessage(), [$e]);
$this->render ('error');
}
}
Within the catch block I've tried both $this->btCacheBlockOutput = true;
and \Cache::disableAll();
but neither works. Is there a way to tell C5 not to cache anything on the current request?
The BlockController in the concrete folder has these protected variables set as standard :
So if you set all these on your block controller.php on false, it should not cache your block.
This will disable the caching of the block (even if the third party connection succeeds).
A different solution is to save the data received from the third party in the database (for example as a json string) and load the data from the database if the third party connection fails... if the third party connection succeeds, you can update the record in the database.
Depending of the answer of the third party service you can set the conditions. Example:
(The code above has not been tested)
More information on storing config values :
https://documentation.concrete5.org/developers/packages/storing-configuration-values
* Edit *
A third option is to purge the cache for that specific page if the call fails.
At the top of your blockcontroller :
In the 'if' when the call to the API fails :
Found at : https://www.concrete5.org/community/forums/5-7-discussion/programmatically-expiring-pages-from-cache