Handling NilObjectException Issue in Linux

Hi,

I have code that I’m using to create a file using SpecialFolder.Documents. It’s working just as expected on my Mac where I’m developing. I build it for Linux and I get NilObjectException not handled. I’m using Try Catch and it gets to the Catch, displays a message using MessageBox to show it’s getting there. Then the application shuts down.

Is there an issue with handling this situation in Linux? Seems like I saw something somewhere but can’t find it now.

Can you post your code and where the exception is occurring and being handled?

Sure, here it is. It creates a text file with the top ten websites stored in a file. This works as it should in Windows and the Mac, just not in Linux.

var TabSTR as string = chr(9)
var x as integer
var recordstr as string
var f as FolderItem
try
  f = SpecialFolder.Documents
  f=f.child("MyStuff").child("MyData").child("toptensites.csv")
  if f.Exists = false then
    'Populate topten array to prepare for saving to disk
    TopTenSites(0,0)="Microsoft"
    TopTenSites(0,1)="https://www.microsoft.com"
    TopTenSites(1,0)="Google"
    TopTenSites(1,1)="https://www.google.com"
    TopTenSites(2,0)="YouTube"
    TopTenSites(2,1)="https://www.youtube.com"
    TopTenSites(3,0)="Amazon"
    TopTenSites(3,1)="https://www.amazon.com"
    TopTenSites(4,0)="Facebook"
    TopTenSites(4,1)="https://www.facebook.com"
    TopTenSites(5,0)="LinkedIn"
    TopTenSites(5,1)="https://www.linkedin.com"
    TopTenSites(6,0)="WikiPedia"
    TopTenSites(6,1)="https://www.wikipedia.com"
    TopTenSites(7,0)="Yahoo"
    TopTenSites(7,1)="https://www.yahoo.com"
    TopTenSites(8,0)="Reddit"
    TopTenSites(8,1)="https://www.reddit.com"
    TopTenSites(9,0)="eBay"
    TopTenSites(9,1)="https://www.ebay.com"
    var theFile as TextOutputStream
    theFile=TextOutputStream.Create(f)
    theFile.Encoding = Encodings.UTF8
    for x=0 to 9
      'build Tab delimited line
      recordstr=App.TopTenSites(x,0)+TabSTR+App.TopTenSites(x,1)+TabSTR+Chr(13)
      theFile.Writeline(recordstr)
    next x
    theFile.close
  end if
catch err as NilObjectException
  MessageBox("Error 2 Creating to ten websites list. Please report to the author")
end try

Also note, that it does get to the Catch Code, displays the message and then the app shuts down. But again, only in Linux.

Why are you putting so much stuff in the Try? Now you have an error, with no idea which statement is giving you the problem. Successively move everything out of the Try except one statement, and see which one you are able to catch. When you know which statement is giving the Nil exception, we can look to see why.

I had tried that earlier and wasn’t having luck. I will work on doing one statement at a time as you recommend until I pin it down. Thanks!

That’s been one of my first thoughts, too.
At the very least, do separate try-catch-es for the FolderItem part, and one for the TextOutputStream part.

Anyway… my guess is that:

  f = SpecialFolder.Documents
  f=f.child("MyStuff")

SpecialFolder.Documents (and others such as .Desktop) don’t work reliably on Linux… at least not on “non-english” systems.
<https://xojo.com/issue/20501>: SpecialFolder.Document fails on Linux with non English language

So… you are likely to get the NOE in f.child("MyStuff").Child...
You could/should even not chain the .child's and check if each (sub)folder exists.
Again - otherwise you might get a NOE in this line of code, but you don’t know which FolderItem’s Child has caused the issue.

Next:

if f.Exists = false then
var theFile as TextOutputStream
theFile=TextOutputStream.Create(f)

You’re trying to create a TextOutputStream, but you aren’t sure that the directory structure exists… since you haven’t checked this above. Another possible cause of an Exception here.

Another possible gotcha one might run into is that the FileSystem on Linux is usally case sensitive.
aFolderItem.Child("toptensites.csv") and aFolderItem.Child("TopTenSites.csv") doesn’t usually matter on macOS/Windows and refer to a single/distinct file (assuming the default file systems are being used, which are not case sensitive), but likely refer to two separate / different files on Linux (with a default case sensitive FileSystem).

1 Like

Tim, this is great information. I will look deeper into my code and what I’m doing. I didn’t even consider the case sensitivity thing so I’ll deal with that too and just make sure everything is the same case.

As far as Language, I’m only using the English version of Linux and not concerned about non English setups at this point.

Thanks!

Should the cause indeed be that SpecialFolder.Documents is not returning what you expect… then please consider using a different “MyAppStuff” folder for TargetLinux.

Quoting from the Unix file-system hierarchy standard:

User specific configuration files for applications are stored in the user’s home directory in a file that starts with the ‘.’ character (a “dot file”). If an application needs to create more than one dot file then they should be placed in a subdirectory with a name starting with a ‘.’ character, (a “dot directory”).

So the starting point for TargetLinux would be SpecialFolder.UserHome (that usually works as expected with Xojo, as far as I know). If that exists, get the .Child(".MyApp"). If it doesn’t exists, create it.

It turns out, it’s not an issue with SpecialFolder.Documents. This issue was Case Sensitivity. Once I corrected the case on all the references to the folders and filename, the issue was resolved.

1 Like

Makes sense as Linux is case sensitive unlike windows
Thanks for the update

1 Like