Skip to content

fix: catch cache error when cache is unavailable - #8

Merged
shavonn merged 4 commits into
mainfrom
unavailable-cache-fail
Jan 15, 2026
Merged

fix: catch cache error when cache is unavailable#8
shavonn merged 4 commits into
mainfrom
unavailable-cache-fail

Conversation

@shavonn

@shavonn shavonn commented Jan 14, 2026

Copy link
Copy Markdown
Contributor

No description provided.

Copilot AI review requested due to automatic review settings January 14, 2026 19:45

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds error handling to gracefully handle cache unavailability scenarios, such as when the cache database doesn't exist during application boot. The changes prevent exceptions from being thrown when cache operations fail, allowing the application to continue functioning without cache.

Changes:

  • Added try-catch blocks around cache operations in active(), forgetCache(), and flushCache() methods
  • Import Throwable class for exception handling
  • Added comprehensive test coverage for cache unavailability scenarios

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
src/ToggleManager.php Added exception handling to cache operations to prevent failures when cache is unavailable
tests/Feature/CacheTest.php Added three test cases covering cache unavailability during active check, forgetCache, and flushCache operations

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/ToggleManager.php Outdated
Comment thread src/ToggleManager.php
Comment thread src/ToggleManager.php
Comment on lines +144 to +147
} catch (Throwable) {
// Cache unavailable
return false;
}

Copilot AI Jan 14, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Catching all Throwable instances is too broad. This catch block could also suppress errors from getDriver()->all() which is unrelated to cache operations. Consider catching more specific exceptions related to cache failures, or restructuring to only wrap the cache-specific operations.

Copilot uses AI. Check for mistakes.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/ToggleManager.php
Comment on lines +122 to +123
try {
return $this->getCache()->forget($this->cacheKey($key));

Copilot AI Jan 14, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The forgetCache() method wraps getCache() in a try-catch, but getCache() is also called in the enable(), disable(), and delete() methods at lines 69, 84, and 99 without error handling. If cache is unavailable when these methods are called, they will throw an exception. Consider adding similar error handling to these call sites or ensuring forgetCache() can be called safely in all contexts.

Copilot uses AI. Check for mistakes.
Comment thread src/ToggleManager.php Outdated
Comment thread tests/Feature/CacheTest.php Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 7 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +57 to +58
Cache::shouldReceive('store')
->andThrow($exception);

Copilot AI Jan 14, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The mock setup using Cache::shouldReceive('store') is incorrect. The code calls forget on the cache repository, not the store method. The mock should call shouldReceive('forget') instead, or mock the entire cache store chain properly to actually trigger exceptions during the forget operation.

Copilot uses AI. Check for mistakes.
Comment on lines +66 to +67
Cache::shouldReceive('store')
->andThrow($exception);

Copilot AI Jan 14, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The mock setup using Cache::shouldReceive('store') is incorrect. The code calls forget on the cache repository in a loop, not the store method. The mock should call shouldReceive('forget') instead, or mock the entire cache store chain properly to actually trigger exceptions during the forget operations.

Copilot uses AI. Check for mistakes.
Comment thread src/ToggleManager.php
Comment on lines +139 to +151
try {
$cache = $this->getCache();

// Clear all known toggles from cache
foreach ($this->getDriver()->all() as $name => $value) {
$cache->forget($this->cacheKey($name));
}
// Clear all known toggles from cache
foreach ($this->getDriver()->all() as $name => $value) {
$cache->forget($this->cacheKey($name));
}

return true;
return true;
} catch (Throwable) {
// Cache unavailable
return false;
}

Copilot AI Jan 14, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The try-catch block around the entire flushCache implementation catches all Throwable exceptions, including those that might be thrown by getDriver()->all(). This could mask genuine driver errors that are unrelated to cache unavailability. Consider wrapping only the cache-specific operations (getCache() and cache->forget()) in the try-catch block, or explicitly checking the exception type before swallowing it.

Copilot uses AI. Check for mistakes.

it('gracefully handles cache unavailability during active check', function () {
// Mock cache to throw a QueryException (simulating database not existing)
$exception = new QueryException('sqlite', 'select * from cache', [], new Exception('Database does not exist'));

Copilot AI Jan 14, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Exception class is used without a proper import statement or full namespace qualifier. Add use Exception; to the imports at the top of the file, or use \Exception in the code.

Copilot uses AI. Check for mistakes.
});

it('gracefully handles cache unavailability during forgetCache', function () {
$exception = new QueryException('sqlite', 'select * from cache', [], new Exception('Database does not exist'));

Copilot AI Jan 14, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Exception class is used without a proper import statement or full namespace qualifier. Add use Exception; to the imports at the top of the file, or use \Exception in the code.

Copilot uses AI. Check for mistakes.
});

it('gracefully handles cache unavailability during flushCache', function () {
$exception = new QueryException('sqlite', 'select * from cache', [], new Exception('Database does not exist'));

Copilot AI Jan 14, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Exception class is used without a proper import statement or full namespace qualifier. Add use Exception; to the imports at the top of the file, or use \Exception in the code.

Copilot uses AI. Check for mistakes.
Comment on lines +47 to +48
Cache::shouldReceive('store')
->andThrow($exception);

Copilot AI Jan 14, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The mock setup using Cache::shouldReceive('store') is incorrect. The code calls methods like remember, forget on the cache repository, not the store method. The mock should call methods like shouldReceive('remember') or shouldReceive('forget') instead, or mock the entire cache store chain properly to actually trigger exceptions during these operations.

Copilot uses AI. Check for mistakes.
@shavonn
shavonn merged commit dfc60f9 into main Jan 15, 2026
17 checks passed
@shavonn
shavonn deleted the unavailable-cache-fail branch January 15, 2026 03:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants