Email Alert - EnsLib.EMail.OutboundAdapter Error
I am running into an error trying to send an Alert Email to test the functionality of IRIS HealthShare Health Connect 2022.1 compared to Cache HealthShare Health Connect 2018.1.3. I was trying to send an Alert email, when I am getting the following error on my EMailAlert operation which is using EnsLib.EMail.OutboundAdpater.
ERROR <Ens>ErrException: <UNDEFINED>FText+4 ^%occMessages *msg -- logged as '-' |
I verified the message to the EMailAlert was populated, so what could be throwing this error...
I found the problem to be with osuwmc.AlertEmail that was created to shorten the data within the email from EnsLib.Email.OutboundAdapter. Can someone take a look at the following code to see if it needs updated for some reason???
Class osuwmc.AlertEmail Extends Ens.Alerting.NotificationOperation [ ClassType = "", ProcedureBlock ]
{
Parameter ADAPTER = "EnsLib.EMail.OutboundAdapter";
Parameter SETTINGS = "IncludeDetails:Basic,SubjectPrefix:Basic,IncludeNodeinSubject:Basic,IncludeManagedAlertHistory:Basic";
Property Adapter As EnsLib.EMail.OutboundAdapter;
/// Control whether detailed information is added to emails sent for standard <class>Ens.AlertRequest</class>
/// messages. The default is 0 (or False) for backward compatibility reasons.
Property IncludeDetails As %Boolean [ InitialExpression = 0 ];
/// Control whether all Managed Alert actions will be included in the email, and the order in which the actions are included.
Property IncludeManagedAlertHistory As %Integer(DISPLAYLIST = ",False,Oldest First,Newest First", VALUELIST = ",0,1,2") [ InitialExpression = 0 ];
/// Prefix to include in the subject of emails sent by this system.
Property SubjectPrefix As %String;
/// This controls whether network information for the node is included in the subject of the outgoing email.
/// If you have many Ensemble installations on multiple systems, this may make it much
/// simpler to identify which system issued an alert.
Property IncludeNodeinSubject As %Boolean [ InitialExpression = 0 ];
/// Property to hold the basic text used to separate sub-sections of each email message.
Property SepLine As %String [ InitialExpression = "===============================================================" ];
Method OnMessage(pRequest As %Library.Persistent, Output pResponse As Ens.Response) As %Status
{
If pRequest.%Extends("Ens.Alerting.NotificationRequest") {
Quit ..OnAlertNotification(pRequest,.pResponse)
}
Quit ..OnAlertRequest(pRequest,.pResponse)
}
/// Main handler for requests of type <class>Ens.AlertRequest</class>.
/// If <property>IncludeDetails</property> is true, then the actual output will be
/// performed in <method>CreateEmailFromAlertRequest</class>.
Method OnAlertRequest(pAlertRequest As Ens.AlertRequest, Output pResponse As Ens.Response) As %Status
{
If ..IncludeDetails {
Set tSC = ..CreateEmailFromAlertRequest(pAlertRequest,.tMailMessage)
If $$$ISERR(tSC) Quit tSC
}
Else {
Set tMailMessage = ##class(%Net.MailMessage).%New()
Set tMailMessage.Subject = "Ensemble alert from " _ ..InstanceName _ ":"_pAlertRequest.SourceConfigName
Set tMailMessage.Charset = "iso-8859-1"
If (pAlertRequest.AlertDestination '= "") {
#; if the Ens.AlertRequest supplied an AlertDestination, then add it to the list of configured Recipients
Set tSC=..Adapter.AddRecipients(tMailMessage, pAlertRequest.AlertDestination) Quit:$$$ISERR(tSC) tSC
}
Set tSC = tMailMessage.TextData.Write(pAlertRequest.AlertText)
Quit:$$$ISERR(tSC) tSC
}
Quit ..Adapter.SendMail(tMailMessage)
}
/// Create a notification email from a standard <class>Ens.AlertRequest</class> object.
Method CreateEmailFromAlertRequest(pAlertRequest As Ens.AlertRequest, Output pMailMessage As %Net.MailMessage) As %Status
{
$$$LOGINFO("CreateEmailFromAlertRequest")
Set tStatus = $$$OK
Try {
Set pMailMessage = ##class(%Net.MailMessage).%New()
Set pMailMessage.Charset = "UTF-8"
Set pMailMessage.Subject = ..SubjectPrefix _ $select(..SubjectPrefix '= "": " ", 1: "")
Do ..GetSystemInfo(,.tSystemName,.tInstanceName,.tNodeName)
If ..IncludeNodeinSubject {
Set pMailMessage.Subject = pMailMessage.Subject _ $$$FormatText($$$Text("Ensemble Alert from configuration item '%1' in system '%2' on node '%3'","Ensemble"),pAlertRequest.SourceConfigName,tSystemName,tNodeName)
}
Else {
Set pMailMessage.Subject = pMailMessage.Subject _ $$$FormatText($$$Text("Ensemble Alert from configuration item '%1' on system '%2'","Ensemble"),pAlertRequest.SourceConfigName,tSystemName)
}
If (pAlertRequest.AlertDestination '= "") {
Set tStatus = ..Adapter.AddRecipients(pMailMessage, pAlertRequest.AlertDestination)
If $$$ISERR(tStatus) Quit
}
Set tNow = $$$timeUTC
Set tNowLocal = $$$timeUTCtoLocal(tNow)
Set tTimeMessage = $select(..IncludeUTCTimes: $$$FormatText($$$Text("Ensemble alert email triggered at %1 [%2 UTC]","Ensemble"),tNowLocal,tNow), 1 : $$$FormatText($$$Text("Ensemble alert email triggered at %1","Ensemble"),tNowLocal))
Set tStatus = pMailMessage.TextData.WriteLine(tTimeMessage)
If $$$ISERR(tStatus) Quit
Set tStatus = ..AddBasicData(pMailMessage,pAlertRequest.AlertText,pAlertRequest.AlertTime,pAlertRequest.SourceConfigName,$get($$$EnsRuntime("Name")),pAlertRequest.SessionId,tSystemName,tInstanceName)
If $$$ISERR(tStatus) Quit
}
Catch {
Set tStatus = $$$EnsSystemError
}
Quit tStatus
}
/// Send a notification email for the incoming <class>Ens.Alerting.NotificationRequest</class> in <var>pNotificationRequest</var>.
Method OnAlertNotification(pNotificationRequest As Ens.Alerting.NotificationRequest, Output pResponse As Ens.Response) As %Status
{
$$$LOGINFO("OnAlertNotification")
Set tStatus = $$$OK
Try {
Set tMailMessage = ##class(%Net.MailMessage).%New()
Set tMailMessage.Charset = "UTF-8"
Set tMailMessage.Subject = $select(..SubjectPrefix '= "": ..SubjectPrefix _ " ", 1: "")
Set tManagedAlert = pNotificationRequest.ManagedAlert
Do ..GetSystemInfo(tManagedAlert,.tSystemName,.tInstanceName,.tNodeName)
If ..IncludeNodeinSubject {
Set tMailMessage.Subject = tMailMessage.Subject _ $$$FormatText($$$Text("Ensemble ManagedAlert from configuration item '%1' in system '%2' on node '%3'","Ensemble"),tManagedAlert.SourceConfigName,tSystemName,tNodeName)
}
Else {
Set tMailMessage.Subject = tMailMessage.Subject _ $$$FormatText($$$Text("Ensemble ManagedAlert from configuration item '%1' on system '%2'","Ensemble"),tManagedAlert.SourceConfigName,tSystemName)
}
If pNotificationRequest.NotificationType '= $$$eAlertNotificationRequest {
Set tUpdateSubject = $case(pNotificationRequest.NotificationType,
$$$eAlertNotificationReminder: $$$Text("Reminder","Ensemble"),
$$$eAlertNotificationEscalationChange: $$$Text("Escalation Change","Ensemble"),
: "")
If (tUpdateSubject '= "") {
Set tMailMessage.Subject = tMailMessage.Subject _ " [" _ tUpdateSubject _ "]"
}
Set tStatus = ..GetUpdateText(pNotificationRequest,.tUpdateText)
If $$$ISERR(tStatus) Quit
//If ($get(tUpdateText) '= "") {
// Set tStatus = tMailMessage.TextData.WriteLine(tUpdateText)
// If $$$ISERR(tStatus) Quit
// Set tStatus = tMailMessage.TextData.WriteLine(..SepLine)
// If $$$ISERR(tStatus) Quit
//}
}
For i=1:1:pNotificationRequest.AlertDestinations.Count() {
Set tDestination = pNotificationRequest.AlertDestinations.GetAt(i)
If (tDestination '= "") {
Set tStatus = tMailMessage.To.Insert(tDestination)
If $$$ISERR(tStatus) Quit
}
}
If $$$ISERR(tStatus) Quit
Set tStatus = ..AddBasicData(tMailMessage,tManagedAlert.AlertText,tManagedAlert.AlertTime,tManagedAlert.SourceConfigName,tManagedAlert.Production,tSystemName,tInstanceName)
//If $$$ISERR(tStatus) Quit
//Set tStatus = tMailMessage.TextData.WriteLine(..SepLine)
//If $$$ISERR(tStatus) Quit
//Set tStatus = tMailMessage.TextData.WriteLine($$$Text("Managed Alert Data","Ensemble"))
//If $$$ISERR(tStatus) Quit
//Set tStatus = tMailMessage.TextData.WriteLine(..SepLine)
//If $$$ISERR(tStatus) Quit
//Set tStatus = tMailMessage.TextData.WriteLine($$$Text("Managed Alert ID","Ensemble") _ ":" _ $char(9,9) _ tManagedAlert.%Id())
//If $$$ISERR(tStatus) Quit
//Set tStatus = tMailMessage.TextData.WriteLine($$$Text("Next Action Time","Ensemble") _ ":" _ $char(9,9) _ $$$timeUTCtoLocal(tManagedAlert.NextActionTime) _ $select(..IncludeUTCTimes: " [" _ tManagedAlert.NextActionTime _ " UTC]", 1: ""))
//If $$$ISERR(tStatus) Quit
//Set tStatus = tMailMessage.TextData.WriteLine($$$Text("Escalation Level","Ensemble") _ ":" _ $char(9,9) _ tManagedAlert.EscalationLevel)
//If $$$ISERR(tStatus) Quit
//Set tStatus = tMailMessage.TextData.WriteLine($$$Text("Current Owner","Ensemble") _ ":" _ $char(9,9) _ $select(tManagedAlert.CurrentOwner = "": "[" _ $$$Text("No current owner","Ensemble") _ "]", 1: tManagedAlert.CurrentOwner))
//If $$$ISERR(tStatus) Quit
//Set tLastActionTime = tManagedAlert.LastActionTime
//Set tStatus = tMailMessage.TextData.WriteLine($$$Text("Last Action Time","Ensemble") _ ":" _ $char(9,9) _ $$$timeUTCtoLocal(tLastActionTime) _ $select(..IncludeUTCTimes: " [" _ tLastActionTime _ " UTC]", 1: ""))
//If $$$ISERR(tStatus) Quit
//Set tStatus = tMailMessage.TextData.WriteLine($$$Text("Next Monitor Time","Ensemble") _ ":" _ $char(9,9) _ $$$timeUTCtoLocal(tManagedAlert.NextMonitorTime) _ $select(..IncludeUTCTimes: " [" _ tManagedAlert.NextMonitorTime _ " UTC]", 1: ""))
//If $$$ISERR(tStatus) Quit
//If ..IncludeManagedAlertHistory {
// Set tStatus = ..AddManagedAlertHistory(tMailMessage,tManagedAlert)
// If $$$ISERR(tStatus) Quit
//}
Set tStatus = ..Adapter.SendMail(tMailMessage)
If $$$ISERR(tStatus) Quit
}
Catch {
Set tStatus = $$$EnsSystemError
}
Quit tStatus
}
/// Helper method to write properties common to basic <class>Ens.AlertRequest</class> and
/// <class>Ens.Alerting.ManagedAlert</class> instances.
Method AddBasicData(pMailMessage As %Net.MailMessage, pAlertText As %String = "", pAlertTime As Ens.DataType.UTC = "", pSourceConfigName As %String = "", pProduction As %String = "", pSessionId As %Integer = "", pSystemName As %String = "", pInstanceName As %String = "") As %Status
{
$$$LOGINFO("AddBasicData")
Set tStatus = $$$OK
Try {
Set tStatus = pMailMessage.TextData.WriteLine(pAlertText)
//$$$Text("Alert Text","Ensemble") _ ":" _ $char(9,9) _
If $$$ISERR(tStatus) Quit
//Set tStatus = pMailMessage.TextData.WriteLine($$$Text("Alert Time","Ensemble") _ ":" _ $char(9,9) _ $select(pAlertTime = "" : $$$Text("Unknown","Ensemble"), 1: $$$timeUTCtoLocal(pAlertTime) _ $select(..IncludeUTCTimes: " [" _ pAlertTime _ " UTC]", 1: "")))
//If $$$ISERR(tStatus) Quit
//Set tStatus = pMailMessage.TextData.WriteLine($$$Text("Production","Ensemble") _ ":" _ $char(9,9) _ $select(pProduction = "": $$$Text("Unknown","Ensemble"), 1: pProduction))
//If $$$ISERR(tStatus) Quit
//Set tStatus = pMailMessage.TextData.WriteLine($$$Text("Source","Ensemble") _ ":" _ $char(9,9) _ pSourceConfigName)
//If $$$ISERR(tStatus) Quit
//If (pSessionId '= "") {
// Set tStatus = pMailMessage.TextData.WriteLine($$$Text("Session","Ensemble") _ ":" _ $char(9,9) _ pSessionId)
// If $$$ISERR(tStatus) Quit
//}
//If (pSystemName '= "") {
// Set tStatus = pMailMessage.TextData.WriteLine($$$Text("System","Ensemble") _ ":" _ $char(9,9) _ pSystemName)
// If $$$ISERR(tStatus) Quit
//}
//If (pInstanceName '= "") {
// Set tStatus = pMailMessage.TextData.WriteLine($$$Text("Instance","%Utility") _ ":" _ $char(9,9) _ pInstanceName)
// If $$$ISERR(tStatus) Quit
//}
//Set tStatus = pMailMessage.TextData.WriteLine($$$Text("Node","Ensemble") _ ":" _ $char(9,9) _ ##class(%SYS.System).GetNodeName())
//If $$$ISERR(tStatus) Quit
}
Catch {
Set tStatus = $$$EnsSystemError
}
Quit tStatus
}
/// Helper method to write out the Managed Alert History for a given ManagedAlert instance.
Method AddManagedAlertHistory(pMailMessage As %Net.MailMessage, pManagedAlert As Ens.Alerting.ManagedAlert) As %Status
{
$$$LOGINFO("AddManagedAlertHistory")
Set tStatus = $$$OK
Try {
Set tActionCount = pManagedAlert.Actions.Count()
If (tActionCount > 0) {
Set tStatus = pMailMessage.TextData.WriteLine(..SepLine)
If $$$ISERR(tStatus) Quit
Set tStatus = pMailMessage.TextData.WriteLine($$$Text("Managed Alert Action History","Ensemble"))
If $$$ISERR(tStatus) Quit
Set tStatus = pMailMessage.TextData.WriteLine(..SepLine)
If $$$ISERR(tStatus) Quit
If ..IncludeManagedAlertHistory = 1 {
Set tStart = tActionCount
Set tIncrement = -1
Set tEnd = 1
}
Else {
Set tStart = 1
Set tIncrement = 1
Set tEnd = tActionCount
}
For i=tStart:tIncrement:tEnd {
Set tAction = pManagedAlert.Actions.GetAt(i)
If $IsObject(tAction) {
Set tStatus = pMailMessage.TextData.WriteLine("(" _ i _ ")" _ $char(9,9) _ $$$Text("Action Time","Ensemble") _ ": " _ $$$timeUTCtoLocal(tAction.ActionTime) _ $select(..IncludeUTCTimes: " [" _ tAction.ActionTime _ " UTC]", 1: ""))
If $$$ISERR(tStatus) Quit
Set tStatus = pMailMessage.TextData.WriteLine($char(9,9) _ $$$Text("User","Ensemble") _ ": " _ tAction.Username)
If $$$ISERR(tStatus) Quit
Set tStatus = pMailMessage.TextData.WriteLine($char(9,9) _ $$$Text("Reason","Ensemble") _ ": " _ tAction.Reason)
If $$$ISERR(tStatus) Quit
#; Only write out changes if there are any
If (tAction.OldValues.Next("") '= "") {
Set tStatus = pMailMessage.TextData.WriteLine($char(9,9) _ $$$Text("Changed Values","Ensemble") _ ":")
If $$$ISERR(tStatus) Quit
Set tPropName = ""
For {
Set tOldValue = tAction.OldValues.GetNext(.tPropName)
If (tPropName = "") Quit
Set tNewValue = tAction.NewValues.GetAt(tPropName)
Set tStatus = pMailMessage.TextData.WriteLine($char(9,9,9) _ tPropName _": '" _ tOldValue _ "' => '" _ tNewValue _ "'")
If $$$ISERR(tStatus) Quit
}
If $$$ISERR(tStatus) Quit
}
Set tStatus = pMailMessage.TextData.WriteLine()
If $$$ISERR(tStatus) Quit
}
}
}
}
Catch {
Set tStatus = $$$EnsSystemError
}
Quit tStatus
}
}
I couldn't even get that class to compile until I set the ENSLIB database to mount R/W. And yes, I was attempting to compile it in a conventional "interoperability-enabled" namespace. That's on I4H 2022.2, fyi.
Does it compile without error on your system?
I see what you mean in 2022.1 it will not compile but however it does compile in 2018.1.3.
2022.1
Compilation started on 05/02/2023 08:05:23 with qualifiers 'cuk'
Compiling class osuwmc.AlertEmail
Compiling routine osuwmc.AlertEmail.1
ERROR: osuwmc.AlertEmail.cls
ERROR: osuwmc.AlertEmail.1(13) : MPP5646 : ##expression on '$$macroText^%occMessages($lb("""Ensemble Alert from configuration item '%1' in system '<PROTECT> 202 macroText+51^%occMessages ^IRIS.Msg("Ensemble","en",2740803238),/ensemble/TEST/mgr/enslib/' on node '%3'""","""Ensemble"""))' failed with an error: %2
TEXT: Set pMailMessage.Subject = pMailMessage.Subject _ $$FormatText^%occMessages(##safeexpression($$macroText^%occMessages($lb("""Ensemble Alert from configuration item '%1' in system '%2' on node '%3'""","""Ensemble"""))),pAlertRequest.SourceConfigName,tSystemName,tNodeName)
ERROR: osuwmc.AlertEmail.1(16) : MPP5646 : ##expression on '$$macroText^%occMessages($lb("""Ensemble Alert from configuration item '%1' on system '<PROTECT> 202 macroText+51^%occMessages ^IRIS.Msg("Ensemble","en",3633416132),/ensemble/TEST/mgr/enslib/'""","""Ensemble"""))' failed with an error: %2
TEXT: Set pMailMessage.Subject = pMailMessage.Subject _ $$FormatText^%occMessages(##safeexpression($$macroText^%occMessages($lb("""Ensemble Alert from configuration item '%1' on system '%2'""","""Ensemble"""))),pAlertRequest.SourceConfigName,tSystemName)
ERROR: osuwmc.AlertEmail.1(25) : MPP5646 : ##expression on '$$macroText^%occMessages($lb("""Ensemble alert email triggered at %1 [<PROTECT> 202 macroText+51^%occMessages ^IRIS.Msg("Ensemble","en",2328442859),/ensemble/TEST/mgr/enslib/ UTC]""","""Ensemble"""))' failed with an error: %2
TEXT: Set tTimeMessage = $select(..IncludeUTCTimes: $$FormatText^%occMessages(##safeexpression($$macroText^%occMessages($lb("""Ensemble alert email triggered at %1 [%2 UTC]""","""Ensemble"""))),tNowLocal,tNow), 1 : $$FormatText^%occMessages(##safeexpression($$macroText^%occMessages($lb("""Ensemble alert email triggered at %1""","""Ensemble"""))),tNowLocal))
ERROR: osuwmc.AlertEmail.1(25) : MPP5646 : ##expression on '$$macroText^%occMessages($lb("""Ensemble alert email triggered at %1""","""Ensemble"""))' failed with an error: <PROTECT> 202 macroText+51^%occMessages ^IRIS.Msg("Ensemble","en",3301903811),/ensemble/TEST/mgr/enslib/
TEXT: Set tTimeMessage = $select(..IncludeUTCTimes: $$FormatText^%occMessages(,tNowLocal,tNow), 1 : $$FormatText^%occMessages(##safeexpression($$macroText^%occMessages($lb("""Ensemble alert email triggered at %1""","""Ensemble"""))),tNowLocal))
ERROR: osuwmc.AlertEmail.cls
ERROR: osuwmc.AlertEmail.1(14) : MPP5646 : ##expression on '$$macroText^%occMessages($lb("""Ensemble ManagedAlert from configuration item '%1' in system '<PROTECT> 202 macroText+51^%occMessages ^IRIS.Msg("Ensemble","en",197323985),/ensemble/TEST/mgr/enslib/' on node '%3'""","""Ensemble"""))' failed with an error: %2
TEXT: Set tMailMessage.Subject = tMailMessage.Subject _ $$FormatText^%occMessages(##safeexpression($$macroText^%occMessages($lb("""Ensemble ManagedAlert from configuration item '%1' in system '%2' on node '%3'""","""Ensemble"""))),tManagedAlert.SourceConfigName,tSystemName,tNodeName)
ERROR: osuwmc.AlertEmail.1(17) : MPP5646 : ##expression on '$$macroText^%occMessages($lb("""Ensemble ManagedAlert from configuration item '%1' on system '<PROTECT> 202 macroText+51^%occMessages ^IRIS.Msg("Ensemble","en",466437042),/ensemble/TEST/mgr/enslib/'""","""Ensemble"""))' failed with an error: %2
TEXT: Set tMailMessage.Subject = tMailMessage.Subject _ $$FormatText^%occMessages(##safeexpression($$macroText^%occMessages($lb("""Ensemble ManagedAlert from configuration item '%1' on system '%2'""","""Ensemble"""))),tManagedAlert.SourceConfigName,tSystemName)
Detected 6 errors during compilation in 0.091s.
2018.1.3
Compilation started on 05/02/2023 08:13:51 with qualifiers 'cuk'
Class osuwmc.AlertEmail is up-to-date.
Compilation finished successfully in 0.199s.
If you set the ENSLIB database to mount read/write, it will compile. I'm wondering if, after recompilation, it will work ...
Working with WRC, our custom code was a copy of EnsLib.Email.AlertOperation that referenced older code that was not referenced anymore in 2022.1. Updated the referenced code and was able to get it to work.
Hi @Scott Roth
Like the @Jeffrey Drumm told, the problem are because the Database ENSLIB are Read Only. The error occur because you are using the Macros $$$FormatText and $$$Text.
When you use $$$Text macro, the macro try to create a entry in the global ^IRIS.Msg. The global ^IRIS.Msg is mapped from ENSLIB database that is by default Read Only. See imagem bellow that the ^IRIS.Msg("ENSEMBLE") is mapped, but the root global ^IRIS.Msg is mapped to the namespace data base.
To solve the compilation error do change calls to $$$Text("some text", "Ensemble") for some think like $$$Text("some text", "MyDomain")
Click in Replace all
Then compile:
For more information see the documentation String Localization and Message Dictionaries
Regrads.