Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions src/http/ErrorHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,19 +48,19 @@ final class ErrorHandler extends \yii\web\ErrorHandler
];

/**
* Template Response instance for error handling.
* Response instance for error handling.
*
* When set, this Response instance will be used as a base for error responses, preserving configured format,
* formatters, and other settings.
*/
private Response|null $templateResponse = null;
private Response|null $response = null;

/**
* Clears all output buffers above the minimum required level.
*
* Iterates through all active output buffers and cleans them, ensuring that only the minimum buffer level remains.
*
* This method is used to discard any existing output before rendering an error response, maintaining a clean output
* This method is used to discard any existing output before rendering an error Response, maintaining a clean output
* state while preserving compatibility with the testing framework.
*
* **PHPUnit Compatibility.**
Expand Down Expand Up @@ -134,16 +134,16 @@ public function handleException($exception): Response
}

/**
* Sets the template Response for error handling.
* Sets the Response for error handling.
*
* The provided Response will be used as a template for error responses, preserving configuration such as format,
* charset, and formatters. The Response will be cleared of any existing data before use.
* The provided Response will be used for error responses, preserving configuration such as format, charset, and
* formatters. The Response will be cleared of any existing data before use.
*
* @param Response $response Template response with desired configuration.
* @param Response $response Response instance with desired configuration.
*/
public function setResponse(Response $response): void
{
$this->templateResponse = $response;
$this->response = $response;
}

/**
Expand Down Expand Up @@ -249,13 +249,13 @@ protected function renderException($exception): Response
/**
* Creates a Response instance for error handling.
*
* Uses the template Response if available, otherwise creates a new instance with default configuration.
* Uses the Response if available, otherwise creates a new instance with default configuration.
*
* @return Response Clean Response instance ready for error content.
*/
private function createErrorResponse(): Response
{
$response = $this->templateResponse ?? new Response($this->defaultResponseConfig);
$response = $this->response ?? new Response($this->defaultResponseConfig);

$response->clear();

Expand Down
63 changes: 51 additions & 12 deletions tests/http/ErrorHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,45 @@ public function testClearOutputCleansAllBuffersInNonTestEnvironment(): void
}
}

public function testCreateErrorResponseClearsExistingResponseData(): void
{
$errorHandler = new ErrorHandler();

$errorHandler->discardExistingOutput = false;

$response = new Response(['charset' => 'UTF-8']);

$response->data = 'Pre-existing data that should be cleared';

$response->setStatusCode(201);
$response->getHeaders()->set('X-Another-Header', 'another-value');
$response->getHeaders()->set('X-Custom-Header', 'custom-value');

$errorHandler->setResponse($response);

$response = $errorHandler->handleException(new Exception('Test exception for response clearing'));

self::assertSame(
500,
$response->getStatusCode(),
"Should set status code to '500' after clearing existing response.",
);
self::assertNotSame(
'Pre-existing data that should be cleared',
$response->data,
"Response data should not be 'Pre-existing data that should be cleared' when reusing existing response " .
'for error handling.',
);
self::assertFalse(
$response->getHeaders()->has('X-Another-Header'),
'All custom headers should be cleared when reusing existing response for error handling.',
);
self::assertFalse(
$response->getHeaders()->has('X-Custom-Header'),
'Custom headers should be cleared when reusing existing response for error handling.',
);
}

public function testHandleExceptionCallsClearOutputWhenEnabled(): void
{
$errorHandler = new ErrorHandler();
Expand Down Expand Up @@ -170,7 +209,7 @@ public function testHandleExceptionWithComplexMessage(): void
);
self::assertIsString(
$response->data,
'Should set response data as string for complex exception.',
'Should set Response data as string for complex exception.',
);
}

Expand All @@ -191,7 +230,7 @@ public function testHandleExceptionWithEmptyMessage(): void
);
self::assertNotNull(
$response->data,
"Should set response data even for 'Exception' with empty message.",
"Should set Response data even for 'Exception' with empty message.",
);
}

Expand All @@ -212,7 +251,7 @@ public function testHandleExceptionWithGenericException(): void
);
self::assertNotEmpty(
$response->data,
'Should set response data with exception information.',
'Should set Response data with exception information.',
);
}

Expand All @@ -235,7 +274,7 @@ public function testHandleExceptionWithLongMessage(): void
);
self::assertNotEmpty(
$response->data,
"Should set response data for 'Exception' with long message.",
"Should set Response data for 'Exception' with long message.",
);
}

Expand Down Expand Up @@ -270,7 +309,7 @@ public function testHandleExceptionWithMultipleDifferentExceptions(): void
}
self::assertNotEmpty(
$response->data,
"Should set response data for exceptions {$index}.",
"Should set Response data for exceptions {$index}.",
);
}
}
Expand All @@ -293,7 +332,7 @@ public function testHandleExceptionWithNestedExceptions(): void
);
self::assertNotEmpty(
$response->data,
'Should set response data for nested exceptions.',
'Should set Response data for nested exceptions.',
);
}

Expand All @@ -314,7 +353,7 @@ public function testHandleExceptionWithRuntimeException(): void
);
self::assertNotEmpty(
$response->data,
'Should set response data for runtime exception.',
'Should set Response data for runtime exception.',
);
}

Expand All @@ -336,7 +375,7 @@ public function testHandleExceptionWithSpecialCharactersInTrace(): void
);
self::assertIsString(
$response->data,
"Should set response data as string for 'Exception' with special trace.",
"Should set Response data as string for 'Exception' with special trace.",
);
}
}
Expand All @@ -358,7 +397,7 @@ public function testHandleExceptionWithUserException(): void
);
self::assertNotEmpty(
$response->data,
'Should set response data for user exception.',
'Should set Response data for user exception.',
);
}

Expand All @@ -379,7 +418,7 @@ public function testHandleExceptionWithZeroCode(): void
);
self::assertNotEmpty(
$response->data,
"Should set response data for 'Exception' with zero code.",
"Should set Response data for 'Exception' with zero code.",
);
}

Expand All @@ -395,11 +434,11 @@ public function testResponseDataIsNotEmpty(): void

self::assertNotEmpty(
$response->data,
'Should always set non-empty response data.',
'Should always set non-empty Response data.',
);
self::assertIsString(
$response->data,
"'Response' data should be string.",
'Response data should be string.',
);
}

Expand Down
Loading