The problem I was having was that when an exception was raised by a problem creating the file (Incorrect file name), the operation will not fall into the Exception::CRLError exception, Instead, it would just crash and I wasn't able to properly handle the exception.
The reason for this is that when using an AX class that runs on the server, the exception never comes back to the client and therefore cannot be handled correctly. I'm using the SalesFormLetter class main method to call my own class after an invoice is generated, and this class (SalesFormLetter) is (1) an abstract class and (2) runs on the server and I really did not want to do this.
A workaorund is to use the TextIO class in AX along with the FileIoPermission. For example, when using the TextIo to create (and/or overwrite) a file, we get a null value when the file could not be created (and/or overwritten). Then, we can throw an exception when the object is null.
In my case I have a central class that handles all errors, so when the TextIO object is null, I call this class and I throw an error, then the error comes back to my method and falls into the Exception::Error exception.
The following is the code
protected void eInvoiceCreateElectronicInvoice()
{
TextIO textIoWrite;
FileIOPermission permission;
;
this.eInvoiceGenerateFileName();
//Get Directory File Path
if(!CompanyInfo::find().KUMDepositoryPDFFilesPath)
KMN_LocalizationSetInfoErrors::routeMessage(KMN_ErrorType::NoFilePath, KMN_InfoErrorOutputType::Error);
//Set the File Path
this.parmInvoiceFilePath(CompanyInfo::find().KUMDepositoryPDFFilesPath);
//Set the company DataAreId
this.parmDataAreaName(this.eInvoiceGetCompanyName());
invoiceFilePath += '\\' + fileName;
try
{
if(WinApi::fileExists(invoiceFilePath))
WinApi::deleteFile(invoiceFilePath);
permission = new FileIOPermission(invoiceFilePath,"RW");
permission.assert();
textIoWrite = New TextIo(invoiceFilePath, "W");
if(textIoWrite == null)
KMN_LocalizationSetInfoErrors::routeMessage(KMN_ErrorType::CLRError, KMN_InfoErrorOutputType::Error);
//Write in file
switch(invoiceFormat)
{
case KumInvoiceFormat::Mexic:
//Document - begin
contData = this.eInvoiceProcessFileValues(KMN_eInvoiceSectionTypeMX::Document_DC);
textIoWrite.write(contData);
textIoWrite = null;
CodeAccessPermission::revertAssert();
break;
}
}
catch(Exception::CLRError)
{
this.eInvoiceProcessTextWriteError();
exc = CLRInterop::getLastException();
if( exc )
{
clrExcMessage = exc.get_Message();
// BP Deviation Documented
strError = CLRInterop::getAnyTypeForObject( clrExcMessage );
innerExc = exc.get_InnerException();
while(innerExc != null)
{
clrExcMessage = innerExc.get_Message();
// BP Deviation Documented
strError = strError + '\n' + CLRInterop::getAnyTypeForObject( clrExcMessage );
innerExc = innerExc.get_InnerException();
}
throw error(strError);
}
}
catch(Exception::Error)
{
this.eInvoiceProcessTextWriteError();
}
}
Nice post.
ReplyDeleteBy using:
new FileIOPermission(invoiceFilePath,'RW').assert();
you avoid two lines of boilerplate code.