Error: Illegal Access (Out of Bounds) in Background.exit()

Hi, I use background for my data field to make web requests. Im updating an old Data field to use a barrel for the web requests (as I want to share the same code base across multiple apps/data fields). I have put the (:background) annotation in the barrel module so that should not be the issue I think. Before I did that I got the same error message when I made the call to a function in the barrel, but that went away after I added the background annotation to the barrel module. 

Here is part of my source code for the BG process: The runtime error occurs when I make the Background.exit(_data) call, to pass the data to the foreground. I get the following in my console:

Error: Illegal Access (Out of Bounds)

Details: Failed invoking <symbol>

using my_barrel;

(:background)
class myBGclass extends Toybox.System.ServiceDelegate {

    function initialize() {
      System.ServiceDelegate.initialize();
	}
    
    function readResponse(data, responseCode) {
    	var _data = {};
    	
    	_data["ResponseCode"] = responseCode;
    	
    	if (responseCode == 200) {
            //copy selected entries from data to _data here
        }
    	Background.exit(_data);
    	
    }
	
	function onTemporalEvent() {
    	// call to makerequest in my_barrel 
    	my_barrel.makerequest(URL, method(:readResponse));	
    }

}

  • Are you trying to use a resource in the background service that's not scoped for the background?

  • Hi Jim, I don't think so. I removed most of the code in my background class and still get the same runtime error: 

    Error: Illegal Access (Out of Bounds)
    Details: Failed invoking <symbol>

    my background class now looks like this:

    using Toybox.WatchUi;
    using Toybox.Application;
    using Toybox.Graphics;
    using Toybox.Communications;
    
    class Background extends WatchUi.Drawable {
    
        hidden var mColor;
    
        function initialize() {
            var dictionary = {
                :identifier => "Background"
            };
    
            Drawable.initialize(dictionary);
        }
    
        function setColor(color) {
            mColor = color;
        }
    
        function draw(dc) {
            dc.setColor(Graphics.COLOR_TRANSPARENT, mColor);
            dc.clear();
        }
    }
    
    (:background)
    class my_BG extends Toybox.System.ServiceDelegate {
    
    
        function initialize() {
          System.ServiceDelegate.initialize();
    	}
        
        function readResponse(responseCode, data) {
            var _data = {};
            if (data.hasKey("ms")) {
                _data["ms"] = data["ms"];
            }
            Background.exit(_data); 	
    
        }
    	
    	function onTemporalEvent() {
        	var _url = "url_to_web_server";
            Communications.makeWebRequest(_url, {"format" => "json"}, {}, method(:readResponse));
        }
        
    }

    and my data field app class looks like this (its a complex data field):

    using Toybox.Application as App;
    using Toybox.Background;
    using Toybox.System as Sys;
    using Toybox.Time;
    
    
    var m_canDoBG=false;
    var m_Data = null;
    var m_responseCode = 0;
    var m_inBackground=false;
    
    const FIVE_MINS = new Time.Duration(5 * 60);
    const SUCCESS = 200;
    
    (:background)
    class my_App extends App.AppBase {
    
        function initialize() {
            AppBase.initialize();
        }
    
        // onStart() is called on application start up
        function onStart(state) {
        }
    
        // onStop() is called when your application is exiting
        function onStop(state) {
        }
    
        //! Return the initial view of your application here
        function getInitialView() {
            
            //check time for last event and calculate time to next
            var _lastEvent = Background.getLastTemporalEventTime();
            var _nextEvent; 
            
            if (_lastEvent != null) {
            	_nextEvent = _lastEvent.add(FIVE_MINS);	
        	} else {
        		_nextEvent = Time.now();
        	}
        	
        	if (Toybox.System has :ServiceDelegate) {
        		m_canDoBG=true;
            	Background.registerForTemporalEvent(_nextEvent);
        	}
        	else {
        		Sys.println("Background not availabe");
        	}
        	
            return [ new my_View() ];
        }
        
        // executed by the bg process when the event occurrs
        function getServiceDelegate(){
        	m_inBackground=true;
            return [new my_BG()];
        }
        
        
        // pass data back to the main process from background
    	function onBackgroundData(data) {
    		
    		if (data != null && (data["Responsecode"] == SUCCESS)) {
    			m_Data = data;
    		}
    		
    		Background.registerForTemporalEvent(Time.now().add(FIVE_MINS));
    	}
    
    }

    Im out of ideas now...

    best regards

    Fredrik

  • I made a stupid mistake. I forgot to add

    using Toybox.Background;