My new article is about error messages which AIF sends to web service consumer application. If exception appeared inside AX business logic while web service performs a request then a client will get a message like "Request Failed. See the Exception Log for details.". It is not the transparent approach, is it. I was requested to resolve this issue in order to provide Web service consumer with detailed information about an error. After short investigation I have figured out that modification should be done in the handleProcessingException() method of the AifRequestProcessor class.
static private AifXml handleProcessingException(AifMessage message, AifInfoLog aifInfoLog)
{
SysExceptionLog exceptionLog;
AifXml faultXml;
AifMessage originalMessage;
;
// We have to get the faultXml first, otherwise doing a infolog.cut() will clear
// the fault object from infolog.
/* I have commented this block of code
if( message && AifEndpoint::propagateErrors(message.sourceEndpointId()) )
{
faultXml = AifFault::faultXml(aifInfoLog.getLastMessage());
}
else
{
faultXml = AifFault::faultXml("@SYS94277");
}*/
faultXml = AifFault::faultXml(infoLogStr(aifInfoLog.getInfoLogData())); // I have add this record
//Write entries to the Exception Log
exceptionLog = new SysExceptionLog();
exceptionLog.writeInfoLogData(strfmt("@SYS95172"), aifInfoLog.getInfoLogData());
aifInfoLog.clearLast();
// Set message status to Error if not processed yet
// The message will exist only if the message has been created, if
// any exception was thrown from processInboundMessage() before the message was created,
// the below call (AifMessageManager::update()) will fail, so we have additional check here.
if( message
&& message.messageId()
&& (!AifMessageManager::isNewMessage(message.messageId())))
{
originalMessage = AifMessageManager::read(message.messageId());
// If message in already in processed or error state, then leave it as is.
if ((originalMessage.status() != AifMessageStatus::Processed) && (originalMessage.status() != AifMessageStatus::Error))
{
originalMessage.status(AifMessageStatus::Error);
AifMessageManager::update(originalMessage, classstr(AifRequestProcessor), true);
}
}
return faultXml;
}
Here is the code of infoLogStr() method:
public static str infoLogStr(InfologData _infologData)
{
str ret;
SysInfoLogEnumerator infoLogEnum = SysInfoLogEnumerator::newData(_infologData);
SysInfologMessageStruct infoMessageStruct;
;
while(infoLogEnum.moveNext())
{
infoMessageStruct = SysInfologMessageStruct::construct(infoLogEnum.currentMessage());
if (ret)
ret += '\r\n';
ret += strFmt('%1: %2',
infoMessageStruct.preFixTextElement(infoMessageStruct.prefixDepth()),
infoMessageStruct.message());
}
return ret;
}
I hope this post will be usefull.
Best regards.
Interesting approach.
ОтветитьУдалитьFrom security prospective it looks like data might be extracted from AX by knowingly sending incorrect requests to webservice. Infolog message might contain confidential information. Permissions to see such info should be managed by AX security. Code above neglects AX security settings.