October: Mail Templates Settings page can throw a fatal error

Created on 5 May 2020  Â·  9Comments  Â·  Source: octobercms/october

  • OctoberCMS Build: 465
  • PHP Version: 7.4.5
  • Database Engine: mysql 15.1

Description:

If a plugin registers a mail partial, the partial is modified in Backend - Settings - Mail Templates, and the plugin is then disabled or removed, the mail templates page becomes unable to load, throwing the fatal exception

Unable to find a registered partial with code: some.mail.partial

Screen Shot 2020-05-05 at 3 10 46 pm

Stack Trace:
|#|Called Code|Document|Line|
|--- |--- |--- |--- |
|77|System\Models\MailPartial->fillFromCode()|~/modules/system/Models/MailPartial.php|48|
|76|System\Models\MailPartial->afterFetch()|~/vendor/october/rain/src/Database/Model.php|168|
|75|October\Rain\Database\Model->October\Rain\Database{closure}(…)|||
|74|call_user_func_array(…)|~/vendor/october/rain/src/Events/Dispatcher.php|233|
|73|October\Rain\Events\Dispatcher->dispatch(…)|~/vendor/october/rain/src/Events/Dispatcher.php|197|
|72|October\Rain\Events\Dispatcher->fire(…)|~/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasEvents.php|148|
|71|Illuminate\Database\Eloquent\Model->fireModelEvent(…)|~/vendor/october/rain/src/Database/Model.php|444|
|70|October\Rain\Database\Model->newFromBuilder(…)|~/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php|260|
|69|Illuminate\Database\Eloquent\Builder->Illuminate\Database\Eloquent{closure}(…)|||
|68|array_map(…)|~/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php|259|
|67|Illuminate\Database\Eloquent\Builder->hydrate(…)|~/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php|1477|
|66|Illuminate\Database\Eloquent\Model->__call(…)|~/vendor/october/rain/src/Extension/ExtendableTrait.php|428|
|65|October\Rain\Database\Model->extendableCall(…)|~/vendor/october/rain/src/Database/Model.php|648|
|64|October\Rain\Database\Model->__call(…)|~/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php|481|
|63|Illuminate\Database\Eloquent\Builder->getModels(…)|~/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php|465|
|62|Illuminate\Database\Eloquent\Builder->get(…)|~/vendor/october/rain/src/Database/Builder.php|141|
|61|October\Rain\Database\Builder->paginate(…)|~/modules/backend/Widgets/Lists.php|602|
|60|Backend\Widgets\Lists->getRecords()|~/modules/backend/Widgets/Lists.php|254|
|59|Backend\Widgets\Lists->prepareVars()|~/modules/backend/Widgets/Lists.php|242|
|58|Backend\Widgets\Lists->render()|~/modules/backend/Behaviors/listcontroller/partials/_container.htm|9|
|57|include(…)|~/modules/system/Traits/ViewMaker.php|247|
|56|Backend\Classes\Controller->makeFileContents(…)|~/modules/backend/Classes/ControllerBehavior.php|153|
|55|Backend\Classes\ControllerBehavior->makeFileContents(…)|~/modules/system/Traits/ViewMaker.php|97|
|54|Backend\Classes\ControllerBehavior->makePartial(…)|~/modules/backend/Behaviors/ListController.php|403|
|53|Backend\Behaviors\ListController->listMakePartial(…)|~/modules/backend/Behaviors/ListController.php|390|
|52|Backend\Behaviors\ListController->listRender(…)|||
|51|call_user_func_array(…)|~/vendor/october/rain/src/Extension/ExtendableTrait.php|414|
|50|Backend\Classes\Controller->extendableCall(…)|~/modules/backend/Classes/Controller.php|184|
|49|Backend\Classes\Controller->__call(…)|~/modules/system/controllers/mailtemplates/index.htm|27|
|48|include(…)|~/modules/system/Traits/ViewMaker.php|247|
|47|Backend\Classes\Controller->makeFileContents(…)|~/modules/system/Traits/ViewMaker.php|109|
|46|Backend\Classes\Controller->makeView(…)|~/modules/backend/Classes/Controller.php|419|
|45|Backend\Classes\Controller->execPageAction(…)|~/modules/backend/Classes/Controller.php|296|
|44|Backend\Classes\Controller->run(…)|~/modules/backend/Classes/BackendController.php|165|
|43|Backend\Classes\BackendController->run(…)|||
|42|call_user_func_array(…)|~/vendor/laravel/framework/src/Illuminate/Routing/Controller.php|54|
|41|Illuminate\Routing\Controller->callAction(…)|~/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php|45|
|40|Illuminate\Routing\ControllerDispatcher->dispatch(…)|~/vendor/laravel/framework/src/Illuminate/Routing/Route.php|212|
|39|Illuminate\Routing\Route->runController()|~/vendor/laravel/framework/src/Illuminate/Routing/Route.php|169|
|38|Illuminate\Routing\Route->run()|~/vendor/laravel/framework/src/Illuminate/Routing/Router.php|658|
|37|Illuminate\Routing\Router->Illuminate\Routing{closure}(…)|~/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php|30|
|36|Illuminate\Routing\Pipeline->Illuminate\Routing{closure}(…)|~/modules/backend/Classes/BackendController.php|68|
|35|Backend\Classes\BackendController->Backend\Classes{closure}(…)|~/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php|131|
|34|Illuminate\Pipeline\Pipeline->Illuminate\Pipeline{closure}(…)|~/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php|53|
|33|Illuminate\Routing\Pipeline->Illuminate\Routing{closure}(…)|~/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php|41|
|32|Illuminate\Routing\Middleware\SubstituteBindings->handle(…)|~/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php|149|
|31|Illuminate\Pipeline\Pipeline->Illuminate\Pipeline{closure}(…)|~/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php|53|
|30|Illuminate\Routing\Pipeline->Illuminate\Routing{closure}(…)|~/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php|49|
|29|Illuminate\View\Middleware\ShareErrorsFromSession->handle(…)|~/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php|149|
|28|Illuminate\Pipeline\Pipeline->Illuminate\Pipeline{closure}(…)|~/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php|53|
|27|Illuminate\Routing\Pipeline->Illuminate\Routing{closure}(…)|~/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php|63|
|26|Illuminate\Session\Middleware\StartSession->handle(…)|~/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php|149|
|25|Illuminate\Pipeline\Pipeline->Illuminate\Pipeline{closure}(…)|~/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php|53|
|24|Illuminate\Routing\Pipeline->Illuminate\Routing{closure}(…)|~/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php|37|
|23|Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse->handle(…)|~/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php|149|
|22|Illuminate\Pipeline\Pipeline->Illuminate\Pipeline{closure}(…)|~/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php|53|
|21|Illuminate\Routing\Pipeline->Illuminate\Routing{closure}(…)|~/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php|66|
|20|Illuminate\Cookie\Middleware\EncryptCookies->handle(…)|~/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php|149|
|19|Illuminate\Pipeline\Pipeline->Illuminate\Pipeline{closure}(…)|~/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php|53|
|18|Illuminate\Routing\Pipeline->Illuminate\Routing{closure}(…)|~/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php|102|
|17|Illuminate\Pipeline\Pipeline->then(…)|~/vendor/laravel/framework/src/Illuminate/Routing/Router.php|660|
|16|Illuminate\Routing\Router->runRouteWithinStack(…)|~/vendor/laravel/framework/src/Illuminate/Routing/Router.php|635|
|15|Illuminate\Routing\Router->runRoute(…)|~/vendor/laravel/framework/src/Illuminate/Routing/Router.php|601|
|14|Illuminate\Routing\Router->dispatchToRoute(…)|~/vendor/october/rain/src/Router/CoreRouter.php|20|
|13|October\Rain\Router\CoreRouter->dispatch(…)|~/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php|176|
|12|Illuminate\Foundation\Http\Kernel->Illuminate\Foundation\Http{closure}(…)|~/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php|30|
|11|Illuminate\Routing\Pipeline->Illuminate\Routing{closure}(…)|~/vendor/barryvdh/laravel-debugbar/src/Middleware/Debugbar.php|51|
|10|Barryvdh\Debugbar\Middleware\Debugbar->handle(…)|~/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php|149|
|9|Illuminate\Pipeline\Pipeline->Illuminate\Pipeline{closure}(…)|~/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php|53|
|8|Illuminate\Routing\Pipeline->Illuminate\Routing{closure}(…)|~/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/CheckForMaintenanceMode.php|46|
|7|Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode->handle(…)|~/vendor/october/rain/src/Foundation/Http/Middleware/CheckForMaintenanceMode.php|25|
|6|October\Rain\Foundation\Http\Middleware\CheckForMaintenanceMode->handle(…)|~/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php|149|
|5|Illuminate\Pipeline\Pipeline->Illuminate\Pipeline{closure}(…)|~/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php|53|
|4|Illuminate\Routing\Pipeline->Illuminate\Routing{closure}(…)|~/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php|102|
|3|Illuminate\Pipeline\Pipeline->then(…)|~/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php|151|
|2|Illuminate\Foundation\Http\Kernel->sendRequestThroughRouter(…)|~/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php|116|
|1|Illuminate\Foundation\Http\Kernel->handle(…)|~/index.php|43|

Completed Bug

All 9 comments

The offending line is https://github.com/octobercms/october/blob/b896924dec1e1e34026377451b2a535bb35ac63d/modules/system/models/MailPartial.php#L100

The problem is that if a mail template record generated by a plugin exists in the database (note this is currently specifically only an issue for partial template types) and then that plugin is later removed or disabled, then this will throw an exception as the partial row exists in the database but a relevant view code for it's backing file cannot be found as the plugin is no longer present / enabled.

Potential solutions include

  • changing this to log an error instead of throwing an exception (which could have potential hidden consequences if it's used elsewhere that would expect an exception, like when rendering)
  • or changing the DB logic to prevent selecting (or exclude after selection) rows that belong to no longer present plugins / disabled plugins

@bennothommo do you have any thoughts on this?

@LukeTowers I'd say the second option is best - it's more graceful and allows the plugin to be reinstalled or re-enabled with the mail partial changes intact at a later stage.

@bennothommo could you take a stab at implementing that or do you need me to?

@Flynsarmy I've taken a look at the steps that you took in order to get the exception, and I unfortunately don't get an exception. I did the following:

  • I registered a mail partial for our October Test plugin, and confirmed that it appeared in the Mail Partials list.
  • I then modified said partial through the Mail Partial editor screen.
  • I then removed the October Test plugin.

When I returned to the Mail Partials list, the partial was still listed, and did not exhibit any issues (I was able to re-edit it for example).

@LukeTowers the Mail Templates section seems to copy partials it detects in plugins to the database immediately on viewing this page. Once that's done, it does not appear to use the partial from the filesystem anymore.

I think this issue lies elsewhere - perhaps from a mail template that is using a partial that has never existed. @Flynsarmy would you be able to dig deeper and see if you can provide us with more info on where to look.

Think this issue can just be closed until someone else experiences it unless @LukeTowers has anything more to add. He was helping me debug the issue at the time.

I deleted the affected records from my DB so that my mail page would start working again. As a result I can no longer replicate.

@LukeTowers let us know if you've been able to replicate it before, and the steps you took if so. I'll be happy to take a look then :)

@bennothommo This specifically came up with the OFFLINE.Mall plugin, see https://cd0da7c0682a.octodock.com:8443/backend/system/mailtemplates for reproduction.

Instructions:

  • Install OFFLINE.Mall
  • Go to mail templates page
  • Disable OFFLINE.Mall
  • Reload mail templates page

Thanks @LukeTowers - will take a look soon.

This issue will be closed and archived in 3 days, as there has been no activity in the last 60 days.
If this issue is still relevant or you would like to see it actioned, please respond and we will re-open this issue.
If this issue is critical to your business, consider joining the Premium Support Program where a Service Level Agreement is offered.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Flynsarmy picture Flynsarmy  Â·  3Comments

EbashuOnHolidays picture EbashuOnHolidays  Â·  3Comments

mittultechnobrave picture mittultechnobrave  Â·  3Comments

jvanremoortere picture jvanremoortere  Â·  3Comments

m49n picture m49n  Â·  3Comments