Folder Create fails on Run, works after Build

Not sure why this code is failing on Run environs but works on a compiled version:

Var f As FolderItem
Var g As FolderItem
Var h As FolderItem
Var filename As String
Var fp1 As String
Var fp2 As String
Var cs1 As Integer
Var d10 As String
Var m10 As String

cs1 = 0

If rday < 10 Then
  d10 = "0" + rday.ToString
End If

If rmonth < 10 Then
  m10 = "0" + rmonth.ToString
End If

filename = uid.ToString + " " + ryear.ToString + "-" + m10 + "-" + d10 + " " + send.ToString + ".txt"
fp1 = ryear.ToString + "-" + m10
fp2 = ryear.ToString + "-" + m10 + "-" + d10

f = New FolderItem("Logs")
g = f.Child(fp1)
h = f.Child(fp1).Child(fp2)

If f <> Nil And f.Exists And f.IsFolder Then
Else
  Try
    f.CreateFolder
  Catch ee As RuntimeException
    cs1 = 0
  End Try
End If


If g <> Nil And g.Exists And g.IsFolder Then
Else
  Try
    g.CreateFolder
  Catch ee As RuntimeException
    cs1 = 0
  End Try
End If

If h <> Nil And h.Exists And h.IsFolder Then
  cs1 = 1
Else
  Try
    h.CreateFolder
    cs1 = 1
  Catch ee As RuntimeException
    cs1 = 0
  End Try
End If

This is frustrating.

If f is nil then f.Child will cause problems and you are assigning those without checking for nil first. I’m also not sure where New FolderItem creates things if you are not using SpecialFolder.

The docs say “it is located in the default folder”, but what is that and is it the same for Run and Build?

Another part of the docs suggest that it would be located inside the application, which usually is readonly, especially for compiled applications.

What’s weird is that the folder g is successfully created while a nested folder within g is NOT created.

Then, after Build, it all works just fine.

Are you on a Mac (I seem to think you are). If you are running the compiled application from a folder other than Applications then all the paths get changed, which may be why you have odd results. I can’t remember what this is called, ah Translocation perhaps. Try using SpecialFolder.Documents for the first FolderItem and see if that solves everything. If it does you are at least have something you can work on.

https://forums.developer.apple.com/forums/thread/724969

This post is under Targets - Windows.

1 Like

So easy to miss that with this forum software. The logic still applies, if the application is moved to the “Applications” folder different rules apply to it being a random document folder. Access rights and all.

:thinking: :thinking: :thinking:
I think @Ian_Kennedy has a solid point here.

For accessibility to the customer / end-user, maybe using Docs or equivalent should be standard practice.

If it is a user facing file then I would suggest SpecialFolder.Documents. If it is an app only log file for you to use in debugging etc. Then there are SpecialFolder.ApplicationData type folders on both platforms. Each of them is writable.

If you are going for SpecialFolder.Documents then perhaps an application specific folder within that?

I would usually expect not to be able to write to the Folder the application is in, even if you can write there the odds are the end user can’t. This becomes especially true in a larger organisation were administrator rights are uncommon.

1 Like

In Run, the debug app is created in a brand new folder, where “Logs” does not exist. That means that both g and h will be Nil. Separate out your folderitem creation to just before you use them.

Very smart. I will be changing that right away.

They’re already created at time of need - we do not need 10,000
empty folders for days the app is opened but no action is recorded.

I meant create the Folderitem variables just before you use them in your code. With

f = New FolderItem("Logs")
g = f.Child(fp1)
h = f.Child(fp1).Child(fp2)

at least h will be nil, if not g as well. Better to move the New Folderitem lines to just before you test them for nil and exists.

f = New FolderItem("Logs")

If f <> Nil And f.Exists And f.IsFolder Then
Else
  Try
    f.CreateFolder
  Catch ee As RuntimeException
    cs1 = 0
  End Try
End If

g = f.Child(fp1)

If g <> Nil And g.Exists And g.IsFolder Then
Else
  Try
    g.CreateFolder
  Catch ee As RuntimeException
    cs1 = 0
  End Try
End If

// h = f.Child(fp1).Child(fp2)
h = g.Child(fp2)

If h <> Nil And h.Exists And h.IsFolder Then
  cs1 = 1
Else
  Try
    h.CreateFolder
    cs1 = 1
  Catch ee As RuntimeException
    cs1 = 0
  End Try
End If
2 Likes

I will try that, and I will move the logs as well.

I tested my app and only the YYYY-MM folder is created on the first run-through.
The second run-through results in the full YYYY-MM-DD nested folder getting created.

The data is simultaneously saved into a SQLite database, so I know that works flawlessly.

I’ll test the JIT placement of the Var constructors.

If you prefer the top placement of the Var you can still put them at the top and then assign them lower down. I know some traditionalists like to specify all the variables up top. By moving the assignments as Tim has suggested you should fine that all folders are created in one pass. as g and h won’t be nil if the prior folder didn’t exist at the start.

@Tim_Hare and @Ian_Kennedy you are absolutely right with your recommendations.
In addition, I recommend avoiding a relative start path. Work in a central path that is accessible to the user. This is the safest way you can ensure that debug and build work under identical conditions. (And you will probably avoid later problems with new operating system restrictions.)

f = SpecialFolder.Documents.Child("Logs")
1 Like

Simple reorganization of the Var assignments worked perfectly.

Your logic is absolutely correct in that the Nil Object is detected upon assignment.

1 Like

Glad, we (collectively) got there.

1 Like