Skip to content

Commit 665a4a2

Browse files
author
Erik Hansen
committed
MAGETWO-37672: Responsive Email Foundation
- Fixed issue where after filter callbacks were applying to email subject when the filtering of email body resulted in an exception - Added unit test to prevent regression - Added production mode error message when filtering results in exception, to prevent users from receiving empty emails
1 parent ca8c5fd commit 665a4a2

File tree

2 files changed

+42
-1
lines changed

2 files changed

+42
-1
lines changed

app/code/Magento/Email/Model/Template/Filter.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -876,10 +876,14 @@ public function filter($value)
876876
try {
877877
$value = parent::filter($value);
878878
} catch (\Exception $e) {
879+
// Since a single instance of this class can be used to filter content multiple times, reset callbacks to
880+
// prevent callbacks running for unrelated content (e.g., email subject and email body)
881+
$this->resetAfterFilterCallbacks();
882+
879883
if ($this->_appState->getMode() == \Magento\Framework\App\State::MODE_DEVELOPER) {
880884
$value = sprintf(__('Error filtering template: %s'), $e->getMessage());
881885
} else {
882-
$value = '';
886+
$value = __("We're sorry, an error has occurred while generating this email.");
883887
}
884888
$this->_logger->critical($e);
885889
}

app/code/Magento/Email/Test/Unit/Model/Template/FilterTest.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,4 +222,41 @@ public function testApplyInlineCssThrowsExceptionWhenDesignParamsNotSet()
222222
{
223223
$this->getModel()->applyInlineCss('test');
224224
}
225+
226+
/**
227+
* Ensure that after filter callbacks are reset after exception is thrown during filtering
228+
*/
229+
public function testAfterFilterCallbackGetsResetWhenExceptionTriggered()
230+
{
231+
$value = '{{var random_var}}';
232+
$exception = new \Exception('Test exception');
233+
$exceptionResult = sprintf(__('Error filtering template: %s'), $exception->getMessage());
234+
235+
$this->appState->expects($this->once())
236+
->method('getMode')
237+
->will($this->returnValue(\Magento\Framework\App\State::MODE_DEVELOPER));
238+
$this->logger->expects($this->once())
239+
->method('critical')
240+
->with($exception);
241+
242+
$filter = $this->getModel(['varDirective', 'resetAfterFilterCallbacks']);
243+
$filter->expects($this->once())
244+
->method('varDirective')
245+
->will($this->throwException($exception));
246+
247+
// Callbacks must be reset after exception is thrown
248+
$filter->expects($this->once())
249+
->method('resetAfterFilterCallbacks');
250+
251+
// Build arbitrary object to pass into the addAfterFilterCallback method
252+
$callbackObject = $this->getMockBuilder('stdObject')
253+
->setMethods(['afterFilterCallbackMethod'])
254+
->getMock();
255+
// Callback should never run due to exception happening during filtering
256+
$callbackObject->expects($this->never())
257+
->method('afterFilterCallbackMethod');
258+
$filter->addAfterFilterCallback([$callbackObject, 'afterFilterCallbackMethod']);
259+
260+
$this->assertEquals($exceptionResult, $filter->filter($value));
261+
}
225262
}

0 commit comments

Comments
 (0)