Skip to end of banner
Go to start of banner

Notification/Certificate Template Development Guide

Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current Restore this Version View Version History

« Previous Version 3 Next »

Introduction

Creating new notification or certificate templates has its challenges since rendering (code execution) is happening in a black box where debugging is difficult and no breakpoints possible.

In order to help with debugging error handling needs to be done more explicitly. For example if a code line throws an Object reference not set to an instance of an object or similar exception we don’t know where and why it happened (no line number or stack trace).

Throwing explicit exceptions and checking variables whether an object lookup was successful would help with debugging and on live systems to look into issues.

Template for the certificate template: SUCO-677 - Getting issue details... STATUS

Other (real world) examples can be found in Git Core repository in

  • CustomerAssets\certificateTemplates

  • CustomerAssets\notificationTemplates

Example of a ‘Bad’ Template

As an example, we have a notification template ‘ProctorExam’ on BCF which tries to access an ExamInstanceAudit to pull information like grade. Due to partial RTS sync the notification is processed before the corresponding ExamInstanceAudit has been synced. As a result, the notification template can’t be rendered and throws a general exception which doesn’t reveal what was missing or where the error happened.

On top of the rendering exception the notification rule target generator ExamProctor doesn’t find the proctor to whom the notification should be sent as well - omitting a recipient if the template did render OK.

Template Code

Line 4 tries to accesses the examInstance's Id but examRepo.QueryById didn't find the exam instance audit and returned null resulting in a null reference exception in line 4 without any knowledge why this happened.

var examRepo = Model.RepositoryFinder.GetRepository<IExamInstanceAuditRepository>();
var examInstanceId = Model.TvmDictionary[TemplateParameterKeyConstants.EXAM_INSTANCE_ID];
var examInstance = examRepo.QueryById(new Guid(examInstanceId));
var urlExamInstanceId = examInstance.Id.ToString();

Error

2021-10-17 09:26:28,652 [ERROR] {Email-NotificationChannel Thread} |NotificationManager.Impl.NotificationChannelEmail| *Core-Service-BCF* Service - Email-NotificationChannel: Could not render email. Template 'ProctorExam' (queue item Id = 'f2d7e15f-2f66-11ec-80fa-0cc47ad9ca93') - Discarding notification - from:no-reply@marinels.com, to:[email address removed (PII)]
MarineLMS.Model.Interfaces.TemplateRenderingException: Razor rendering failed ---> System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.edcbfeaacddafcfbc.Execute()
   at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context)
   at MarineLMS.Model.Impl.TemplateHelper.RenderTemplate(String templateString, IDictionary`2 parameters, IRepositoryFinder repositoryFinder)
   --- End of inner exception stack trace ---
   at MarineLMS.Model.Impl.TemplateHelper.RenderTemplate(String templateString, IDictionary`2 parameters, IRepositoryFinder repositoryFinder)
   at MarineLMS.NotificationManager.Impl.NotificationChannelEmail.DeliverItem(ICoreUnitofWork uow, IChannelQueueItem item)

Pitfalls for Template Rendering

Lookup of information which are not present in Model.TvmDictionary should be used with caution (i.e. lookup model object via Id from the DB). Not all information may be available at the time of template rendering (keep partial RTS sync in mind).

Always check if the requested object does exist - check for null. If an object was expected and is required for rendering throw an explicit error with as much detail as possible so debugging and live-site-investigations is easier.

Develop Print Layout

Chrome has the ability to render a print version of a page instead of needing to open the print menu to see the print layout. This could reduce dev time for the print version.

Open Chrome > Dev Tools (F11)-> three dots -> More tools -> Rendering -> emulate CSS media type

Set page size to whatever page you need to print: