I have a list of files with (sometimes) sound files attached that will each be played whenever the list/row changes. For some reason on the built app (maybe only Mac), if I attempt to open another list, and there is no sound file, a nilobject is thrown.
Not sure why it would not throw the exception in the IDE as you say. Otherwise it would be easy to break on the exception. Maybe just set the IDE (if you haven’t) to “Break on Exceptions” anyway.
Off the top of my head, since you say that some rows will not have sounds anyway, I would nest the code that plays the sound in a Try/Catch
I thought the debuglog only worked in debug mode.
I know the line of code which is being jumped over. I have no proof. The sounds are being ran if there a text path is there. If there is no text, then the “if” statement is NO.
How do I find out what is happening?
The sounds are being ran if there a text path is there. If there is no text, then the “if” statement is NO.
Is the “text path” the file path to the sound file?
Given the failure to find the NEO, my suggestion was to just handle it. Something like
Try
//put in your code that plays the sound
Catch somethingGoofy as nilObjectException
// We don't know what threw the exception, but we won't crash trying to play a nil sound
End Try
Good Night. If you respond, I’ll respond after celebrations tomorrow.
I’ll post the code for playing the sound. When I look at it I have got it covered with Trys, but maybe someone has ideas.
This is the method inside of the method which does the actual playing of the sound. There are 2 possible sounds held in the array WhchSound. This is all where the NilObject is being probably being thrown, but it shouldn’t even get here.
//Public Function PlayngSnd(Idx As Integer) As Integer
//stStop is True if starting sound False if stopping
//idx is the index being requested. If -1 then whatever
If idx = 0 Then
If me.WhchSound(0) = Nil Then
me.WSIdx = -1
Return me.WSIdx//This hold the index of the pair of sounds
Else
me.WSIdx = 0
End If
ElseIf idx = 1 Then
If me.WhchSound(1) = Nil Then
me.WSIdx = -1
Return me.WSIdx
Else
me.WSIdx = 1
End If
ElseIf idx = -1 Then
If me.WhchSound(0) <> Nil Then
me.WSIdx = 0
ElseIf me.WhchSound(1) <> Nil Then
me.WSIdx = 1
Else
me.WSIdx = -1
Return me.WSIdx
End If
End If//If ids = 0 Then
If me.WhchSound(me.WSIdx).IsPlaying Then//Triangle
me.WhchSound(WSIdx).Stop
//dWin.TurnOff.RunMode = Timer.RunModes.Off
Else
Try
me.WhchSound(WSIdx).Play
//dWin.TurnOff.RunMode = Timer.RunModes.Multiple
//me.SegmentAt(segmentIndex).Title = &u25a0
Catch
me.WSIdx = -1
MessageBox "An error occured while attempting to play this sound." + EOL + "The sound file may be corrupt."
End Try
End If
Return me.WSIdx
This is the part of the method which calls the other.
if App.ExstsTruu(ArMnt.WhchSndFItm(0)) Then
ArMnt.WhchSound(0) = ArMnt.WhchSound(0).Open(ArMnt.WhchSndFItm(0))
SoundBttons.SegmentAt(0).Enabled = True
Try
If SndAutoPlay And ArMnt.PlayngSnd(0) = 0 Then
TurnOff(0).RunMode = Timer.RunModes.Multiple//This is a timer to turn it
End If
Catch //If an error occurs, code here will be run.
'WordSndTimer.Mode = Xojo.Core.Timer.Modes.Off
MessageBox "An Error occured while Attempting to Play the Sound " + ArMnt.WhchSndFItm(0).Name + EOL + "The Sound File may be Corrupt."
SoundBttons.SegmentAt(0).Enabled = False
End Try
ElseIf BeingEdited = False Then
SoundBttons.SegmentAt(0).Enabled = False
End If
I’m curious as to how the WhchSound() array is populated. My initial thought when you first posted is that this could be related to the fact that you get an exception when running the compiled app but not while debugging, and is why I asked “How are the sound files “attached” to the app? Did you drag them into the IDE, or are they external?”, but your posted code doesn’t answer that question as far as I can see.
I note that there’s no Nil check before
If me.WhchSound(me.WSIdx).IsPlaying
so if WhchSound(me.WSIdx) is Nil, it will definitely throw an NoE on that line.
This makes sense, regarding the difference between debug and build behavior. If your sound files are in the project folder, it’s possible that the .debug app can see them, but a built app (originally in the Build folder but ultimately sent anywhere) cannot. But like Julia says, we don’t know how you acquire the sound files, so this is guesswork.
However you do it, I would think that the audio files need to wind up in your app’s Resources folder when you build.
Personally, Im not a fan of ELSEIF. It’s perfectly valid, but it can make the code hard to follow.
I also note that in some places you use me.WSIdx and in others just WSIdx… if there is a global WSIdx property somewhere, these are different variables.
Can I suggest this (feel free to ignore)
dim Ret as integer = -1 //assume the worst
//kill the current sound
if me.WhchSound(idx) <> nil and me.WhchSound(idx).IsPlaying then
me.WhchSound(idx).Stop
end if
// swap -1 for 0 if 0 is valid
if idx = -1 and me.WhchSound(0) <> Nil then
Ret = 0
else
//idx is not -1, so check if it is valid
if me.WhchSound(idx) <> nil then
Ret = idx
end if
end if
me.WSIdx = Ret
if Ret > -1 and me.WhchSound(Ret) <> nil then
//start playing
Try
me.WhchSound(Ret).Play
Catch
Ret = -1
MessageBox "An error occured while attempting to play this sound." + EOL + "The sound file may be corrupt."
End Try
End if
Return Ret
Something to keep in mind is that the location of the app when running is typically right next to the app. If you’ve hard coded any paths to files, you can easily get a nilobjectexception from the built app if the files are not in the same relative place. Try moving your built app into the same directory as your project and see if it still fails.
Thanks. Everything is stored as text and I have a system of partial paths for sound and image files. That partial path is stored as text and recreated as Native when I need it.
I haven’t added network capability yet, because I keep on finding little bugs.
Even partial paths are likely going to be an issue cross platform. It could be better to add items to the resources folder and access them via SpecialFolder.Resource( “Somefile.extension” )