From 52c52df6dd985c3dd78fdfca65ce24dd864f0989 Mon Sep 17 00:00:00 2001 From: ionutboangiu Date: Wed, 23 Oct 2024 21:50:59 +0300 Subject: [PATCH] Define a separate func for the diamErr constructor Added back the warning logs for backwards compatibility. Now passing err.Error() as Error-Message AVP where applicable. Added comments and revised err messages. --- agents/diamagent.go | 17 ++++++++--------- agents/libdiam.go | 45 ++++++++++++++++++++++++++------------------- 2 files changed, 34 insertions(+), 28 deletions(-) diff --git a/agents/diamagent.go b/agents/diamagent.go index f60dfb497..50f8f9d50 100644 --- a/agents/diamagent.go +++ b/agents/diamagent.go @@ -189,7 +189,7 @@ func (da *DiameterAgent) handleMessage(c diam.Conn, m *diam.Message) { if err != nil { utils.Logger.Err(fmt.Sprintf("<%s> decoding app: %d, err: %s", utils.DiameterAgent, m.Header.ApplicationID, err.Error())) - writeOnConn(c, diamErrMsg(m, diam.NoCommonApplication, "")) + writeOnConn(c, diamErrMsg(m, diam.NoCommonApplication, err.Error())) return } dCmd, err := m.Dictionary().FindCommand( @@ -198,7 +198,7 @@ func (da *DiameterAgent) handleMessage(c diam.Conn, m *diam.Message) { if err != nil { utils.Logger.Warning(fmt.Sprintf("<%s> decoding app: %d, command %d, err: %s", utils.DiameterAgent, m.Header.ApplicationID, m.Header.CommandCode, err.Error())) - writeOnConn(c, diamErrMsg(m, diam.CommandUnsupported, "")) + writeOnConn(c, diamErrMsg(m, diam.CommandUnsupported, err.Error())) return } diamDP := newDADataProvider(c, m) @@ -214,10 +214,9 @@ func (da *DiameterAgent) handleMessage(c diam.Conn, m *diam.Message) { utils.RemoteHost: utils.NewLeafNode(c.RemoteAddr().String()), }, } - handleErr := newDiamErrHandler(m, reqVars, da.cgrCfg, da.filterS) if da.caps.IsLimited() { if err := da.caps.Allocate(); err != nil { - handleErr(c, diam.TooBusy) + diamErr(c, m, diam.TooBusy, reqVars, da.cgrCfg, da.filterS) return } defer da.caps.Deallocate() @@ -231,14 +230,14 @@ func (da *DiameterAgent) handleMessage(c diam.Conn, m *diam.Message) { utils.Logger.Warning( fmt.Sprintf("<%s> failed retrieving Session-Id err: %s, message: %s", utils.DiameterAgent, err.Error(), m)) - handleErr(c, diam.UnableToComply) + diamErr(c, m, diam.UnableToComply, reqVars, da.cgrCfg, da.filterS) return } // cache message data needed for building up the ASR if errCh := engine.Cache.Set(utils.CacheDiameterMessages, sessID, &diamMsgData{c, m, reqVars}, nil, true, utils.NonTransactional); errCh != nil { utils.Logger.Warning(fmt.Sprintf("<%s> failed message: %s to set Cache: %s", utils.DiameterAgent, m, errCh.Error())) - handleErr(c, diam.UnableToComply) + diamErr(c, m, diam.UnableToComply, reqVars, da.cgrCfg, da.filterS) return } } @@ -276,14 +275,14 @@ func (da *DiameterAgent) handleMessage(c diam.Conn, m *diam.Message) { utils.Logger.Warning( fmt.Sprintf("<%s> error: %s processing message: %s", utils.DiameterAgent, err.Error(), m)) - handleErr(c, diam.UnableToComply) + diamErr(c, m, diam.UnableToComply, reqVars, da.cgrCfg, da.filterS) return } if !processed { utils.Logger.Warning( fmt.Sprintf("<%s> no request processor enabled, ignoring message %s from %s", utils.DiameterAgent, m, c.RemoteAddr())) - handleErr(c, diam.UnableToComply) + diamErr(c, m, diam.UnableToComply, reqVars, da.cgrCfg, da.filterS) return } a, err := diamAnswer(m, 0, false, @@ -292,7 +291,7 @@ func (da *DiameterAgent) handleMessage(c diam.Conn, m *diam.Message) { utils.Logger.Warning( fmt.Sprintf("<%s> err: %s, replying to message: %+v", utils.DiameterAgent, err.Error(), m)) - handleErr(c, diam.UnableToComply) + diamErr(c, m, diam.UnableToComply, reqVars, da.cgrCfg, da.filterS) return } writeOnConn(c, a) diff --git a/agents/libdiam.go b/agents/libdiam.go index aeb1ce3f3..2da8d9159 100644 --- a/agents/libdiam.go +++ b/agents/libdiam.go @@ -454,28 +454,35 @@ func diamAnswer(m *diam.Message, resCode uint32, errFlag bool, return } -func newDiamErrHandler(m *diam.Message, reqVars *utils.DataNode, cfg *config.CGRConfig, - filterS *engine.FilterS) func(c diam.Conn, resCode uint32) { - return func(c diam.Conn, resCode uint32) { - tnt := cfg.GeneralCfg().DefaultTenant - tmz := cfg.GeneralCfg().DefaultTimezone - aReq := NewAgentRequest(newDADataProvider(nil, m), reqVars, - nil, nil, nil, nil, tnt, tmz, filterS, nil) - if err := aReq.SetFields(cfg.TemplatesCfg()[utils.MetaErr]); err != nil { - writeOnConn(c, diamErrMsg(m, diam.UnableToComply, - fmt.Sprintf("failed to parse *err template: %v", err))) - return - } - diamAns, err := diamAnswer(m, resCode, true, aReq.Reply, tmz) - if err != nil { - writeOnConn(c, diamErrMsg(m, diam.UnableToComply, - fmt.Sprintf("failed to construct error response: %v", err))) - return - } - writeOnConn(c, diamAns) +// diamErr handles Diameter error scenarios by attempting to build a customized error answer +// based on the *err template. +func diamErr(c diam.Conn, m *diam.Message, resCode uint32, reqVars *utils.DataNode, cfg *config.CGRConfig, + filterS *engine.FilterS) { + tnt := cfg.GeneralCfg().DefaultTenant + tmz := cfg.GeneralCfg().DefaultTimezone + aReq := NewAgentRequest(newDADataProvider(nil, m), reqVars, + nil, nil, nil, nil, tnt, tmz, filterS, nil) + if err := aReq.SetFields(cfg.TemplatesCfg()[utils.MetaErr]); err != nil { + utils.Logger.Warning(fmt.Sprintf( + "<%s> message: %s - failed to parse *err template: %v", + utils.DiameterAgent, m, err)) + writeOnConn(c, diamErrMsg(m, diam.UnableToComply, + fmt.Sprintf("failed to parse *err template: %v", err))) + return } + diamAns, err := diamAnswer(m, resCode, true, aReq.Reply, tmz) + if err != nil { + utils.Logger.Warning(fmt.Sprintf( + "<%s> message: %s - failed to build error answer: %v", + utils.DiameterAgent, m, err)) + writeOnConn(c, diamErrMsg(m, diam.UnableToComply, + fmt.Sprintf("failed to build error answer: %v", err))) + return + } + writeOnConn(c, diamAns) } +// diamErrMsg creates a Diameter error answer with the given result code and optional error message. func diamErrMsg(m *diam.Message, resCode uint32, msg string) *diam.Message { ans := m.Answer(resCode) ans.Header.CommandFlags = diam.ErrorFlag