regression on FuseJS/Camera between 0.21 and 0.22

Testing on OSX, Fuse 0.21.0.6730 and 0.22.0.6996. Affected device preview on iOS (running via XCode), but I did not test Android.

After taking a picture or selecting one from Library, the app dies with “Could not open file” when using 0.22. Works just fine on 0.21. As far as I can tell, the crash happens when the app tries to read the picture taken/selected to display it in UX: <ImageFill File="{imagePath}" StretchMode="UniformToFill" />.

Repro:

<App>

    <JavaScript>
    var Observable = require('FuseJS/Observable');
    var Camera = require("FuseJS/Camera");
    var CameraRoll = require("FuseJS/CameraRoll");
    var ImageTools = require("FuseJS/ImageTools");

    var showPic = Observable(false);
    var imagePath = Observable('');

    function displayImage(image) {
      showPic.value = true;
      imagePath.value = image.path;
    };

    function takePicture() {
      Camera.takePicture().then(
        function(image) {
          var args = { desiredWidth:640, desiredHeight:640, mode:ImageTools.SCALE_AND_CROP, performInPlace:true };
          ImageTools.resize(image, args).then(
            function(image) {
              CameraRoll.publishImage(image);
              displayImage(image);
            }
          ).catch(
            function(reason) {
              console.log("Couldn't resize image: " + reason);
            }
          );
        }
      ).catch(
        function(reason) {
          console.log("Couldn't take picture: " + reason);
        }
      );
    };

    function selectImage() {
      CameraRoll.getImage().then(
        function(image) {
          console.log("received image: "+image.path+", "+image.width+"/"+image.height);
          displayImage(image);
        }
      ).catch(
        function(reason) {
          console.log("Couldn't get image: "+reason);
        }
      );
    };

    module.exports = {
        'takePicture':takePicture,
        'selectImage':selectImage,
        'showPic':showPic,
        'imagePath':imagePath
    }
    </JavaScript>

    <StackPanel Alignment="VerticalCenter">

        <WhileTrue Value="{showPic}">
            <Circle Height="200" Width="200" Alignment="Center">
                <ImageFill File="{imagePath}" StretchMode="UniformToFill" />
            </Circle>
        </WhileTrue>

        <Grid Columns="1*,10,1*" Margin="20">
            <Panel Height="50" HitTestMode="LocalBoundsAndChildren">
                <Text Value="Take photo" Alignment="Center" TextColor="#fff" FontSize="16" />
                <Clicked>
                    <Callback Handler="{takePicture}" />
                </Clicked>
                <Rectangle Fill="#faa" CornerRadius="3" />
            </Panel>
            <Panel />
            <Panel Height="50" HitTestMode="LocalBoundsAndChildren">
                <Text Value="Upload image" Alignment="Center" TextColor="#fff" FontSize="16" />
                <Clicked>
                    <Callback Handler="{selectImage}" />
                </Clicked>
                <Rectangle Fill="#aaf" CornerRadius="3" />
            </Panel>
        </Grid>

    </StackPanel>

</App>

On it!

Just tested this on Android device preview, it throws the same thing. Here’s the trace from Monitor:

LOG: InternalError: UnhandledException: Couldn't open file:  in Outracks.Simulator.GeneratedApplication</usr/local/share/uno/Packages/FuseCore/0.32.11/$.uno:307>
LOG: InternalError: Failed to properly reset. Try exiting Fuse and restarting.: Couldn't open file:  in Outracks.Simulator.GeneratedApplication</usr/local/share/uno/Packages/Outracks.Simulator.Client.Uno/0.1.0/$.uno:174>
ERROR: Couldn't open file: 
    Uno.IO.IOException occured.
       at Uno.IO.FileSystemImpl.CppXliOpenRead(string)
       at Uno.IO.File.OpenRead(string)
       at Fuse.Scripting.JSFileSource.OpenRead()
       at Uno.UX.FileSource.ReadAllBytes()
       at Fuse.Resources.FileImageSourceImpl.SyncLoad()
       at Fuse.Resources.FileImageSource.set_File(Uno.UX.FileSource)
       at Fuse.Internal.ImageContainer.OnFileAdded(Uno.UX.FileSource)
       at Uno.Collections.ObservableList`1.Add(T)
       at Fuse.Internal.ImageContainer.set_File(Uno.UX.FileSource)
       at Fuse.Drawing.ImageFill.set_File(Uno.UX.FileSource)
       at Uno.Reflection.CppFunction.Invoke(object,object[])
       at Outracks.Simulator.Reflection.Native.TryInvokeExtension.TryInvoke(Uno.Reflection.IFunction,object,object[])
       at Outracks.Simulator.Reflection.Native.NativeReflection.SetPropertyValue(object,Outracks.Simulator.Bytecode.TypeMemberName,object)
       at Outracks.Simulator.Runtime.ScopeClosure.Evaluate(Outracks.Simulator.Bytecode.WriteProperty)
       at Outracks.Simulator.Bytecode.Expression.Match`1(Uno.Func<Outracks.Simulator.Bytecode.ReadVariable, T>,Uno.Func<Outracks.Simulator.Bytecode.Literal, T>,Uno.Func<Outracks.Simulator.Bytecode.Lambda, T>,Uno.Func<Outracks.Simulator.Bytecode.MethodGroup, T>,Uno.Func<Outracks.Simulator.Bytecode.IsType, T>,Uno.Func<Outracks.Simulator.Bytecode.LogicalOr, T>,Uno.Func<Outracks.Simulator.Bytecode.Instantiate, T>,Uno.Func<Outracks.Simulator.Bytecode.CallLambda, T>,Uno.Func<Outracks.Simulator.Bytecode.CallStaticMethod, T>,Uno.Func<Outracks.Simulator.Bytecode.CallDynamicMethod, T>,Uno.Func<Outracks.Simulator.Bytecode.ReadStaticField, T>,Uno.Func<Outracks.Simulator.Bytecode.ReadProperty, T>,Uno.Func<Outracks.Simulator.Bytecode.WriteProperty, T>,Uno.Func<Outracks.Simulator.Bytecode.AddEventHandler, T>,Uno.Func<Outracks.Simulator.Bytecode.RemoveEventHandler, T>)
       at Outracks.Simulator.Runtime.ScopeClosure.Evaluate(Outracks.Simulator.Bytecode.Expression)
       at Outracks.Simulator.Runtime.ScopeClosure.Execute(Uno.Collections.IEnumerable<Outracks.Simulator.Bytecode.Statement>)
       at Outracks.Simulator.Runtime.ScopeClosure.Execute(Outracks.Simulator.Bytecode.Lambda,object[])
       at Outracks.Simulator.Runtime.LambdaClosure.Func(object,object)
       at Outracks.Simulator.Runtime.LambdaClosure.Action(object,object)
       at Outracks.Simulator.Runtime.UxProperty`1.Set(T,Uno.UX.IPropertyListener)
       at Fuse.Reactive.DataBinding`1.TryPushAsMarshalledValue(object)
       at Fuse.Reactive.DataBinding`1.PushValue(object)
       at Fuse.Reactive.DataBinding`1.Fuse.Reactive.IObserver.OnSet(object)
       at Fuse.Reactive.Observable.Subscription..ctor(Fuse.Reactive.Observable,Fuse.Reactive.IObserver)
       at Fuse.Reactive.Observable.Subscribe(Fuse.Reactive.IObserver)
       at Fuse.Reactive.DataBinding`1.NewValue(object)
       at Fuse.Reactive.SegmentObserver.HandlePath(object,string)
       at Fuse.Reactive.SegmentObserver.HandleNewDataContext(object)
       at Fuse.Reactive.SegmentObserver.HandleObject(Fuse.Reactive.ObjectMirror)
       at Fuse.Reactive.SegmentObserver.HandlePath(object,string)
       at Fuse.Reactive.SegmentObserver.Init(object,string)
       at Fuse.Reactive.BindAttempt.TryBind()
       at Fuse.Reactive.BindAttempt..ctor(Fuse.Reactive.PathObserver)
       at Fuse.Reactive.PathObserver.RestartBinding()
       at Fuse.Reactive.PathObserver..ctor(Fuse.Reactive.ContextBinding,Fuse.Node,string)
       at Fuse.Reactive.ContextBinding.OnRooted()
       at Fuse.Reactive.DataBinding`1.OnRooted()
       at Fuse.Binding.Root(Fuse.Node)
       at Fuse.Node.RootBindings()
       at Fuse.Node.OnRooted()
       at Fuse.Visual.OnRooted()
       at Fuse.Elements.Element.OnRooted()
       at Fuse.Controls.Control.OnRooted()
       at Fuse.Controls.LayoutControl.OnRooted()
       at Fuse.Controls.Shape.OnRooted()
       at Fuse.Node.RootInternal(Fuse.Visual)
       at Fuse.Node.Relate(Fuse.Visual,Fuse.Node)
       at Fuse.Visual.OnAdded(Fuse.Node)
       at Fuse.Visual.Insert(int,Fuse.Node)
       at Fuse.Triggers.Trigger.AddContent(Fuse.Node)
       at Fuse.Triggers.Trigger.Start()
       at Fuse.Triggers.Trigger.PlayEnd(bool,[Uno.Action])
       at Fuse.Triggers.Trigger.DirectActivate([Uno.Action])
       at Fuse.Triggers.Trigger.Activate([Uno.Action])
       at Fuse.Triggers.WhileTrigger.SetActive(bool)
       at Fuse.Triggers.WhileValue`1.set_Value(T)
       at Fuse.Triggers.WhileBool.set_Value(bool)
       at Uno.Reflection.CppFunction.Invoke(object,object[])
       at Outracks.Simulator.Reflection.Native.TryInvokeExtension.TryInvoke(Uno.Reflection.IFunction,object,object[])
       at Outracks.Simulator.Reflection.Native.NativeReflection.SetPropertyValue(object,Outracks.Simulator.Bytecode.TypeMemberName,object)
       at Outracks.Simulator.Runtime.ScopeClosure.Evaluate(Outracks.Simulator.Bytecode.WriteProperty)
       at Outracks.Simulator.Bytecode.Expression.Match`1(Uno.Func<Outracks.Simulator.Bytecode.ReadVariable, T>,Uno.Func<Outracks.Simulator.Bytecode.Literal, T>,Uno.Func<Outracks.Simulator.Bytecode.Lambda, T>,Uno.Func<Outracks.Simulator.Bytecode.MethodGroup, T>,Uno.Func<Outracks.Simulator.Bytecode.IsType, T>,Uno.Func<Outracks.Simulator.Bytecode.LogicalOr, T>,Uno.Func<Outracks.Simulator.Bytecode.Instantiate, T>,Uno.Func<Outracks.Simulator.Bytecode.CallLambda, T>,Uno.Func<Outracks.Simulator.Bytecode.CallStaticMethod, T>,Uno.Func<Outracks.Simulator.Bytecode.CallDynamicMethod, T>,Uno.Func<Outracks.Simulator.Bytecode.ReadStaticField, T>,Uno.Func<Outracks.Simulator.Bytecode.ReadProperty, T>,Uno.Func<Outracks.Simulator.Bytecode.WriteProperty, T>,Uno.Func<Outracks.Simulator.Bytecode.AddEventHandler, T>,Uno.Func<Outracks.Simulator.Bytecode.RemoveEventHandler, T>)
       at Outracks.Simulator.Runtime.ScopeClosure.Evaluate(Outracks.Simulator.Bytecode.Expression)
       at Outracks.Simulator.Runtime.ScopeClosure.Execute(Uno.Collections.IEnumerable<Outracks.Simulator.Bytecode.Statement>)
       at Outracks.Simulator.Runtime.ScopeClosure.Execute(Outracks.Simulator.Bytecode.Lambda,object[])
       at Outracks.Simulator.Runtime.LambdaClosure.Func(object,object)
       at Outracks.Simulator.Runtime.LambdaClosure.Action(object,object)
       at Outracks.Simulator.Runtime.UxProperty`1.Set(T,Uno.UX.IPropertyListener)
       at Fuse.Reactive.DataBinding`1.TryPushAsValue(object)
       at Fuse.Reactive.DataBinding`1.PushValue(object)
       at Fuse.Reactive.DataBinding`1.Fuse.Reactive.IObserver.OnSet(object)
       at Fuse.Reactive.Observable.Set.SendMessage(Fuse.Reactive.Observable.Subscription)
       at Fuse.Reactive.Observable.Operation.Perform()
       at Fuse.Reactive.ThreadWorker.ProcessUIMessages()
       at Fuse.UpdateListener.Invoke()
       at Fuse.UpdateManager.Update(Fuse.Stage)
       at Fuse.UpdateManager.Update()
       at Fuse.AppBase.OnUpdate()
       at Outracks.Simulator.Application.OnUpdate()
       at Fuse.App.OnFrameCallback(double,double)

The issue seems to be that you ended up binding to an empty path. That should not crash the application so I have created an issue for this.