Skip to main content

Notifications

Announcements

No record found.

Community site session details

Community site session details

Session Id :
Finance | Project Operations, Human Resources, ...
Answered

System.IO throwing errors when running as batch job

(0) ShareShare
ReportReport
Posted on by

Hi Experts.

I get error while deleting the file using system.io delete during batch job. however get no error & fiile get successfuly deleted when running same code as non btach.

Please suggest fix for following

1. How do i get to delete the file in batch & non batch mode

2. How do i get to move the file in batch & non batch mode.  

3. Currently it does not capture the details of why the batch job failed, what can i do to improvise my catch block so that it capture the details of generic failures i.e. exception from info cllass's add exception .

Here is the complete code. Thanks in advance.

public void run()
{

    str                          fileNameString,fileNamePath;
    MyCustom  msg;
    System.IO.DirectoryInfo     directory,processedDirectory;
    System.IO.FileInfo[]        files;
    System.IO.FileInfo          file;
    //Set                 permissionSet;
    InteropPermission           permission;
    counter                     filesCount;
    FilePath                    processedFilePath,processedFileCompletePath;
    Filename                    filename,filepath,fileType;
    Filename                    tmpFilePath;
    Filename                    tmpFileNameShort;
    Filename                    tmpFileExt;

    counter                     loop;
    str                         fileNameOnly,fileNameTemp;
    filetype                    type;
    boolean                     skipZeroTrans;
    boolean wrongFileFormat = false;

    #FILE

    try
    {

        permission  = new InteropPermission(InteropKind::ClrInterop);
        permission.assert();

        select   myCustomTable;
      
        skipZeroTrans = myCustomTable.skipZeroTransVal;

        directory   = new System.IO.DirectoryInfo(@myCustomTable.FilePath);
        filepath = @myCustomTable.myCustomTablelFilePath;
        
        processedDirectory = new System.IO.DirectoryInfo(@myCustomTable.ProcessedFilePath);
        processedFilePath = @myCustomTable.ProcessedFilePath;

        files       = directory.GetFiles("*.csv*");
        filesCount  = files.get_Length();

        for (loop = 0; loop < filesCount; loop  )
        {
            file = files.GetValue(loop);
            fileNameTemp = file.get_FullName();

            filename = fileNameTemp;
            info(strFmt("filename: %1",filename));


             if (strLen(fileNameTemp) > 0)
                {
                    [tmpFilePath, tmpFileNameShort, tmpFileExt] = fileNameSplit(fileNameTemp);
                    fileNameString= tmpFileNameShort   tmpFileExt;
                    info(strFmt('Import filename=%1', fileNameTemp));

                    if(tmpFilePath && tmpFileNameShort && tmpFileExt == #csv)
                    {
                   
                        msg = this.processFile(fileNameTemp,skipZeroTrans);
                 
                    }
                    else
                    {
                        if (strLen(tmpFilePath) == 0)
                        {
                            error("Filepath not specified");
                        }

                        wrongFileFormat = true;
                        Error (strFmt("%1 unsupported fileType", tmpFileExt));
                    }

                    if ( strScan(msg,"Error",0,strLen(msg)))
                    {
                        throw error("Error encountered while processing file");
                    }

                    this.myWriteMessage(tmpFilePath,tmpFileNameShort,msg);
                    info(msg);
                    System.IO.File::Delete(filename);                                                                             //TODO 1   RUNS FINE IN NON BATCH MODE BUT ERRORS IN BATCH MODE  ONCE FIXED USE either DELETE or MOVE 


                    // CHECK FILE MOVE CODE
                  /* // processedFilePath = processedFilePath   "\n\\"  tmpFileNameShort;
                    //permissionSet =  new Set(Types::Class);
                    //permissionSet.add(new FileIOPermission(filename, #io_write));
                    //permissionSet.add(new FileIOPermission(processedFilePath, #io_write));
                    //permissionSet.add(new InteropPermission(InteropKind::ClrInterop));
                    //CodeAccessPermission::assertMultiple(permissionSet);
                   // CodeAccessPermission::revertAssert();
                    //processedFileCompletePath = processedFilePath "\n\\" tmpFileNameShort  tmpFileExt;
                    //System.IO.File::Move(filename,processedFileCompletePath);
                    //System.IO.File::Move(fileName, newFileName); */                                                             //TODO 2 ERRORS IN BOTH BATCH & NON BATCH MODE
                }


        }// for ends
    } // Try ends
    catch
    {

        if (wrongFileFormat == true)
        {
            this.myWriteMessage(tmpFilePath,tmpFileNameShort,msg);
            throw Error (strFmt("%1 Unsupported file type", fileType));
        }


       else if (Exception::Error &&  Exception::CLRError)
        {
           
            this.myWriteMessage(tmpFilePath,tmpFileNameShort,msg);
            throw Error (msg   "Exception" );                                                                        //TODO 3  Explore how can you replace "Exception" with exception from info add exception so as to capture the details of geneic failures.

        }


        else if (Exception::DuplicateKeyException && Exception::DuplicateKeyExceptionNotRecovered)
        {
    
                                     
             this.myWriteMessage(tmpFilePath,tmpFileNameShort,msg);
             throw error(strFmt("Error encountered while processng the file. \n Read log at %1 path for details",tmpFilePath));

        }

    }
}//Run method ends

Thanks

Mav

  • Mav Profile Picture
    Mav on at
    RE: System.IO throwing errors when running as batch job

    Thanks all for responding this mystr = directory + @"\"+mystr+@".txt"; fixed my moving file issue.

  • RE: System.IO throwing errors when running as batch job

    Hi Martin,

    Thank you for great comments and the rich-format makes the code looks better.

  • Martin Dráb Profile Picture
    Martin Dráb 231,409 Most Valuable Professional on at
    RE: System.IO throwing errors when running as batch job

    Mav, \ is a special character - notice that you also use it for \n. You need \\ to represent \, or use a verbatim string (e.g. str path = @'c:\temp\file.txt').

    Leo.Wang, please use Insert > Insert Code (in the rich-formatting view) to paste source code. This is the result:

    Boolean                  res = true;
    System.Text.UTF8Encoding encode;
    System.IO.FileStream     fs;
    System.Byte []           info;
    System.String            fileName;
    System.IO.StreamWriter   sw;
    str                      mystr;
    System.Exception         ex;
    
    try
    {
    	new InteropPermission(InteropKind::ClrInterop).assert();
    	encode = new System.Text.UTF8Encoding(true);
    	info  =  encode.GetBytes("Create test content");
    	mystr = System.Guid::NewGuid().ToString("N");
    	mystr = directory   @"\" mystr @".txt";
    	fileName = mystr;
    	fs = System.IO.File::Create(fileName);
    	fs.Write(info, 0, info.get_Length());
    	fs.Close();
    	fs.Dispose();
    	sw = System.IO.File::AppendText(fileName);
    	sw.Write("Modify test content");
    	sw.Close();
    	sw.Dispose();
    	System.IO.File::Delete(fileName);
    	CodeAccessPermission::revertAssert();
    }
    catch(Exception::CLRError)
    {
    	ex = ClrInterop::getLastException();
    	if (ex != null)
    	{
    	   ex = ex.get_InnerException();
    	   if (ex != null)
    	   {
    		   error(ex.ToString());
    	   }
    }
    CodeAccessPermission::revertAssert();
    res = false;

    A few comments to this code:

    • Close() and Dispose() do the same thing; you don't have to call them both.
    • You're not disposing fs and sw objects if an exception occurs
    • You don't have to call CodeAccessPermission::revertAssert() if you don't have other code in your method when the permissions shouldn't apply. Usually it's better to design small single-purpose methods rather and revertAssert() isn't typically needed in such a case. Also, you call revertAssert() twice (in the successful scenario, which isn't necessary).
    • You could replace most of your code with System.IO.File::WriteAllText().
  • Mav Profile Picture
    Mav on at
    RE: System.IO throwing errors when running as batch job

    I think i found the issue which is that my processedFilePath does not contain "\" this in end which leads my

    processedFileCompletePath to something like "C:\myFiles\ Processed file myFile1.xls"

    where as objective is to get values like below C:\myFiles\Processed file \ myFile1.xls (Which is correct path)

    For processedFilePath  i have tried using both below approach but none of below approach helped me in getting "\" after the filepath.

     processedDirectory = new System.IO.DirectoryInfo(@myCustomTable.myProcessedFilePath);

     processedFilePath = @myCustomTable.myProcessedFilePath;

    & if i forcefully add "\" by using code

    processedFileCompletePath = processedFilePath+"\n\\"+tmpFileNameShort+ tmpFileExt;

    I get illegal value in path error.

    Can you please suggest a fix.

  • Verified answer
    RE: System.IO throwing errors when running as batch job

    Here is an demo to catch the error information when using .net:

       Boolean                  res = true;

       System.Text.UTF8Encoding encode;

       System.IO.FileStream     fs;

       System.Byte []           info;

       System.String            fileName;

       System.IO.StreamWriter   sw;

       str                      mystr;

       System.Exception         ex;

       ;

       try

       {

           new InteropPermission(InteropKind::ClrInterop).assert();

           encode = new System.Text.UTF8Encoding(true);

           info  =  encode.GetBytes("Create test content");

           mystr = System.Guid::NewGuid().ToString("N");

           mystr = directory + @"\"+mystr+@".txt";

           fileName = mystr;

           fs = System.IO.File::Create(fileName);

           fs.Write(info, 0, info.get_Length());

           fs.Close();

           fs.Dispose();

           sw = System.IO.File::AppendText(fileName);

           sw.Write("Modify test content");

           sw.Close();

           sw.Dispose();

           System.IO.File::Delete(fileName);

           CodeAccessPermission::revertAssert();

       }

       catch(Exception::CLRError)

       {

           ex = ClrInterop::getLastException();

           if (ex != null)

           {

               ex = ex.get_InnerException();

               if (ex != null)

               {

                   error(ex.ToString());

               }

           }

           CodeAccessPermission::revertAssert();

           res = false;

       }

  • Suggested answer
    Mav Profile Picture
    Mav on at
    RE: System.IO throwing errors when running as batch job

    I am able to delete the fils via system IO using myTextIO.finalize()

    However when trying to move the file from 1 folder to other i keep getting the below error message even when there is no file in the destination folder

    System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.IO.IOException: Cannot create a file when that file already exists.

      at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)

      at System.IO.File.InternalMove(String sourceFileName, String destFileName, Boolean checkHost)

      at Dynamics.Ax.Application.myclass.run.() in myclass.run.xpp:line 105

      --- End of inner exception stack trace --

    Change made to code shared earlier for moving file to different folder.

    //System.IO.File::Delete(filename);  commented delete action
    
    
                  
    processedFileCompletePath = processedFilePath tmpFileNameShort  tmpFileExt;  // Uncommented these 2 lines for moving the file
    System.IO.File::Move(filename,processedFileCompletePath);
    
    
                   

  • Mav Profile Picture
    Mav on at
    RE: System.IO throwing errors when running as batch job

    I think this may go away by using Text IO .finalize(). Will try & use .finalize() to see if it helps & update this thread.

  • Mav Profile Picture
    Mav on at
    RE: System.IO throwing errors when running as batch job

    Hi Martin after using CLRInterop::getLastException().ToString(); i got this in error message

    System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.IO.IOException: The process cannot access the file 'Filepath\myCSVFILE1.csv' because it is being used by another process.

      at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)

      at System.IO.File.InternalDelete(String path, Boolean checkHost)

      at Dynamics.Ax.Application.myClass.Run() in myClass.run.xpp:line 96  (LINE 96 is  System.IO.File::Delete(filename))

      --- End of inner exception stack trace ---

    Thanks

    Mav

  • Mav Profile Picture
    Mav on at
    RE: System.IO throwing errors when running as batch job

    Thanks Martin, will look in into your suggestion.

    BTW Captured this in my event viewer

    "Object Server 01:  

      Microsoft.Dynamics.Ax.Xpp.BreakException: Exception of type 'Microsoft.Dynamics.Ax.Xpp.BreakException' was thrown. at Microsoft.Dynamics.Ax.MSIL.Interop.throwException(Int32 ExceptionValue) at Microsoft.Dynamics.Ax.MSIL.cqlClassIL.create(Int32 classId, Object[] parameters, Type[] types, Object[] varargs, Type[] varargsTypes, Object ILObject) at Microsoft.Dynamics.Ax.Xpp.XppObjectBase.createKernelClass(Object[] parameters, Type[] paramTypes, Object[] varargs) at Dynamics.Ax.Application.SkipAOSValidationPermission.new() at Dynamics.Ax.Application.SkipAOSValidationPermission..ctor() at Dynamics.Ax.Application.BatchRun.serverFinishTask(Int64 batchId, Boolean isErrorCaught, Exception exception, BatchRunType batchRunType, Int32 infoCnt, Boolean , Boolean ) in BatchRun.serverFinishTask.xpp:line 10 at Dynamics.Ax.Application.BatchRun.@serverFinishTask(Int64 batchId, Boolean isErrorCaught, Exception exception, BatchRunType batchRunType, Boolean ) at Dynamics.Ax.Application.BatchRun.serverFinishTask(Int64 batchId, Boolean isErrorCaught, Exception exception) at BatchRun::serverFinishTask(Object[] ) at Microsoft.Dynamics.Ax.Xpp.ReflectionCallHelper.MakeStaticCall(Type type, String MethodName, Object[] parameters) at BatchIL.taskThreadEntry(Object threadArg)

    "

    Thanks

    Mav

  • Verified answer
    Martin Dráb Profile Picture
    Martin Dráb 231,409 Most Valuable Professional on at
    RE: System.IO throwing errors when running as batch job

    I would focus on the code in question; the status in AX doesn't sound relevant to me. If you have problem with debugging, try recompiling code and generating full CIL. And review your debugging setup in Visual Studio (e.g. "Enable just my code").

    Regarding your catch clause, I have no idea what you hope to achieve by conditions like if (Exception::Error &&  Exception::CLRError). It makes no sense to me.

    To catch CLR exceptions, use something like this:

    catch (Exception::CLRError)
    {
    	throw error(AifUtil::getClrErrorMessage());
    }
    catch
    {
        ...
    }

    getClrErrorMessage() gives you just a message of the inner exception. If you want more details, use CLRInterop::getLastException().ToString().

    I don't know what code you have in myWriteMessage(), but I suggest removing it for now, because it may be throwing an exception when you're trying to handle other exceptions.

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Daivat Vartak – Community Spotlight

We are honored to recognize Daivat Vartak as our March 2025 Community…

Announcing Our 2025 Season 1 Super Users!

A new season of Super Users has arrived, and we are so grateful for the daily…

Kudos to the February Top 10 Community Stars!

Thanks for all your good work in the Community!

Leaderboard

#1
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 292,516 Super User 2025 Season 1

#2
Martin Dráb Profile Picture

Martin Dráb 231,409 Most Valuable Professional

#3
nmaenpaa Profile Picture

nmaenpaa 101,156

Leaderboard

Product updates

Dynamics 365 release plans