(NRF/GATT).getPrimaryService() error handling issue

Posted on
  • I'm going nuts. Trying to discover devices, services, characteristics.
    When everything exists - no problem.
    But I'd like to handle that a service is not defined.

    This is my simplified code:

    NRF.requestDevice({filters: [{namePrefix: 'Puck.js'}]}).then(dev=>{
      console.log("device found", dev);
      return dev.gatt.connect();
    }).then(conn=>{
      console.log("connected", conn);
      return conn.getPrimaryService(0x464F);
    }).then(s=>{
      console.log("service found", s);
    },f=>{
      console.log("no service found", f);
    }).catch(e=>{
      console.log( "error:", e );
    });
    

    On execution neither f=>{ nor .catch(e=>{ are called:

    device found BluetoothDevice {
      "id": "f9:2d:30:24:38:a4 random",
      "rssi": -51,
      "services": [  ],
      "data": new ArrayBuffer([2, 1, 5, 13, 9, 80, 117, 99, 107, 46, 106, 115, 32, 51, 56, 97, 52]),
      "name": "Puck.js 38a4"
     }
    connected BluetoothRemoteGATTServer {
      "device": BluetoothDevice {
        "id": "f9:2d:30:24:38:a4 random",
        "rssi": -51,
        "services": [  ],
        "data": new ArrayBuffer([2, 1, 5, 13, 9, 80, 117, 99, 107, 46, 106, 115, 32, 51, 56, 97, 52]),
        "name": "Puck.js 38a4",
        "gatt":  ...
       },
      "connected": true }
    Uncaught Error: Unhandled promise rejection: No Services found
    

    Is this a bug or have I messed up my Promises?

  • And another one with NRF:

    Uncaught Error: Unhandled promise rejection: undefined
     at line 12 col 30
      return device.gatt.connect().then(conn => {
    

    (Seems to occur when I try to connect a device that is already connected by another puck at this time)

    Any way to catch this?

  • Have you updated your firmware to 1v90? The promise returning undefined rather than an error sounds like a 1v88 issue.

    If you're getting Uncaught Error: Unhandled promise rejection then you should be able to catch it with a .catch though.

    I guess it could be something strange with the promise implementation and your use of the second argument to then.

    Have you tried just:

    NRF.requestDevice({filters: [{namePrefix: 'Puck.js'}]}).then(dev=>{
      console.log("device found", dev);
      return dev.gatt.connect();
    }).then(conn=>{
      console.log("connected", conn);
      return conn.getPrimaryService(0x464F);
    }).then(s=>{
      console.log("service found", s);
    }).catch(e=>{
      console.log( "error:", e );
    });
    
  • Yes, everything updated to 1v90 already.
    The single .catch at the end of the chain was the first that I tried.
    And when that didn't work I added the second parameter in .then - but both don't work.

    Is the single, final .catch supposed to work for every rejected Promise in the whole queue?
    If yes, looks like something with the Promise handling is not working...

  • Yes, I believe it's supposed to. I'll take a look and see what's up.

  • Looks like there's a problem when a rejected promise is returned inside a promise.

    new Promise((x,y)=>x()).then(dev=>{
      return new Promise((x,y)=>y("Uh-oh"));
    }).then(s=>{
      console.log("ok", s);
    }).catch(e=>{
      console.log("error", e);
    });
    

    Sorry about that - I'm really surprised that one slipped through.

  • Ok, it's fixed now. Updated firmware should be attached.

    With how busy I am at the moment it's unlikely there will be a 1v91 release until the new year, but at least you can use this firmware until that point. Both methods of catching (.then(a,b) or .then(a).catch(b)) should work with the new one.


    1 Attachment

  • Wow. That was quick. Thank you very much.
    Will test it when I'm home tonight. (Forgot to bring the pucks to work :)

    I just got into setting up the build process and had a look into the source as well.
    So I should be able to run build myself from now and maybe getting a bit involved too.

  • That'd be great! Let me know if there are any issues - I think the build instructions may need a bit of updating - this thread may help: http://forum.espruino.com/conversations/­297524/

  • Actually I did look at that thread (OS X here too) and was able to get a first build (untested):

    $ git show
    commit f795885490e38b0947f322dee1c9fc600101273a­
    Merge: 5135ed5 8b0f789
    Author: Gordon Williams <gw@pur3.co.uk>
    Date:   Mon Dec 19 07:59:17 2016 +0000
    
        Merge pull request #992 from MaBecker/patch-3
        
        update pinStateToString() and dependencies
    
    $ ls -l *.zip
    -rw-r--r--  1 user  staff  342147 20 Dez 08:09 espruino_1v90.2075_puckjs.zip
    

    ;-)

  • @Gordon: Just updated and tested: espruino_1v90.5_puckjs.zip is confirmed to work and catch the promise.
    Thanks a lot.

  • @Gordon: I think there is still something going on. I had been banging my head against my table trying to get one of my pucks controlling the other via bluetooth and kept getting the unhandled promise rejection error. Then I found this thread and updated the firmware to 1v90.5. However, that didn't solve my problem.

    To make sure it wasn't something dumb on my part, I copied and pasted the code from the Controlling Other Pucks example (from the "Making it Faster" section). After pressing the button roughly 25 - 30 times I either get the error or no error displays in the console but the master puck stops controlling the other puck. The puck itself is still responsive to console commands, so it doesn't appear to be freezing or anything strange like that. My best guess is that the busy variable gets set to true and never reset when the error occurs so the code in the body of the sendToggle function is never executed. That doesn't help understand the error, though.

    For completeness, the console looks like this once the error occurs:

    Uncaught error: Unhandled promise rejection: undefined
     at line 34 col 47
    ...tic.writeValue("toggle()\n").then(fun­ction() {
                                      ^
    
    in function called from system
    
  • FYI The updated firmware provided in the previous post seems to be missing in the "binaries folder".

  • @goliatone you are right.
    Gordon said in post #7:

    Ok, it's fixed now. Updated firmware should be attached.

    With how busy I am at the moment it's unlikely there will be a 1v91 release until the new year, but at least you can use this firmware until that point.

    So this is no official build. You only find it uploaded further up in this thread.

  • Does the 1v90.12 firmware work better?

    I didn't want to update the official build before I went on holiday as it'd annoy a lot of people if it broke something and then I didn't fix it for 2 weeks - but I'll release 1v91 soon

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

(NRF/GATT).getPrimaryService() error handling issue

Posted by Avatar for ChristianW @ChristianW

Actions