Skip to content

Fix HtmlRenderer to handle FriendlyException attribute safely #147

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

shuangjie
Copy link

@shuangjie shuangjie commented Apr 17, 2025

Q A
Is bugfix?
New feature?
Breaks BC?
Fixed issues Issue #16

This PR fixes two issues in HtmlRenderer:

  1. Fixed a TypeError in htmlEncode() function by properly converting Throwable object to string before encoding
  2. Added safe handling for the FriendlyException attribute when the class is not available

These changes allow the error handler to work properly with different versions of the friendly-exception package, making it more robust.

The changes are needed because some tests were failing with:

  • TypeError: HtmlRenderer::htmlEncode(): Argument #1 ($content) must be of type string, RuntimeException given
  • Error: Attribute class "Yiisoft\FriendlyException\Attribute\FriendlyException" not found

This implementation adds proper type checking and class existence verification to prevent errors.

Copy link

codecov bot commented Apr 17, 2025

Codecov Report

Attention: Patch coverage is 42.85714% with 4 lines in your changes missing coverage. Please review.

Project coverage is 80.32%. Comparing base (44f49fa) to head (40f70ae).

Files with missing lines Patch % Lines
src/Renderer/HtmlRenderer.php 42.85% 4 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##             master     #147      +/-   ##
============================================
- Coverage     80.55%   80.32%   -0.24%     
- Complexity      210      213       +3     
============================================
  Files            19       19              
  Lines           679      686       +7     
============================================
+ Hits            547      551       +4     
- Misses          132      135       +3     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@vjik
Copy link
Member

vjik commented Apr 18, 2025

What is Yiisoft\FriendlyException\Attribute\FriendlyException ?

@vjik vjik added the status:under development Someone is working on a pull request. label Apr 18, 2025
@shuangjie
Copy link
Author

What is Yiisoft\FriendlyException\Attribute\FriendlyException ?

This class is from a potential future implementation of PHP 8 attributes in the friendly-exception package, related to Issue #16 (yiisoft/friendly-exception#16).

Currently, this class doesn't exist in the official friendly-exception package. My PR adds defensive coding to ensure error-handler works correctly both with current versions (where this class doesn't exist) and with future versions (if/when PHP 8 attributes are implemented).

I created test files that use this attribute to verify the defensive coding works properly. I've marked these tests as skipped when the attribute class is not available.

If you prefer, I can remove the attribute-related test files and only keep the safety checks for the htmlEncode method, which fixes a real issue with TypeError when encoding exception objects.

@samdark
Copy link
Member

samdark commented Apr 19, 2025

I like the concept. It allows marking expceptions as friendly without extending the interface and is a good addition to what we already have. That's of course, works for static text solutions only but in many cases these are enough.

@samdark samdark requested a review from xepozz April 19, 2025 19:25
Copy link
Member

@xepozz xepozz left a comment

Choose a reason for hiding this comment

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

Let's extract getting FE names to a class and reuse it?

// Check if the exception class has FriendlyException attribute
try {
$reflectionClass = new ReflectionClass($throwable);
if (class_exists('Yiisoft\FriendlyException\Attribute\FriendlyException')) {
Copy link
Member

Choose a reason for hiding this comment

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

Use full class name notation without quotes

Suggested change
if (class_exists('Yiisoft\FriendlyException\Attribute\FriendlyException')) {
if (class_exists(\Yiisoft\FriendlyException\Attribute\FriendlyException::class)) {

try {
$reflectionClass = new ReflectionClass($throwable);
if (class_exists('Yiisoft\FriendlyException\Attribute\FriendlyException')) {
$attributes = $reflectionClass->getAttributes('Yiisoft\FriendlyException\Attribute\FriendlyException');
Copy link
Member

Choose a reason for hiding this comment

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

Same

$name = $friendlyExceptionAttribute->name . ' (' . $name . ')';
}
}
} catch (\Throwable) {
Copy link
Member

Choose a reason for hiding this comment

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

Where do you expect an exception? I'd remove try/catch

Copy link
Author

Choose a reason for hiding this comment

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

You're right, the try/catch block isn't necessary here. When checking for the FriendlyException attribute, it would be better to let any exceptions propagate normally, making potential issues easier to discover. I'll remove the try/catch block. Thank you for the suggestion!

@@ -20,6 +25,22 @@
}
$isFriendlyException = $throwable instanceof FriendlyExceptionInterface;
$solution = $isFriendlyException ? $throwable->getSolution() : null;

// Check if the exception class has FriendlyException attribute
if ($solution === null && class_exists('Yiisoft\FriendlyException\Attribute\FriendlyException')) {
Copy link
Member

Choose a reason for hiding this comment

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

Same

…ibute

- Remove unnecessary try/catch blocks as suggested in PR review
Copy link
Author

@shuangjie shuangjie left a comment

Choose a reason for hiding this comment

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

done

@samdark samdark requested a review from xepozz April 21, 2025 11:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status:under development Someone is working on a pull request.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants