How to fix: localhost/:1 Uncaught (in promise) DOMException: GATT Error Unknown.?

I am writing a app in Vue.JS that will read the UV Index from a Bluetooth LE UV Detector. How it works: the user must hit a button and connect with a device called “UV Detector”, and then the device will show the device info and UV index.

For now, I am trying to get the app to show the device info, but that is where I am stuck.

I get this error: Uncaught (in promise) DOMException: GATT Error Unknown.

The code that I am writing was modified from my earlier work, where it read skin data from a skincare device. I did not get that error reading the data from the previous device. But for this particular device, it’s giving me this error, and I’m pulling my hair over how to fix this.

My code:

methods: {
          getDevice: function () {
                if (navigator.bluetooth) {
                    this.bluetoothDevice = navigator.bluetooth.requestDevice({
                        filters: [{
                            name: "UV Detector",
                        }],
                        optionalServices: [this.deviceServices.deviceInfoSvc, this.deviceServices.batteryInfoSvc] // Required to access service later.
                    })
                        .then(device => {
                            this.bluetoothDevice = device;
                            this.instruction = "Device is connected. Press the device against your skin before you hit 'Press Data'.";
                            device.addEventListener('gattserverdisconnected', this.onDisconnected);
                            return device.gatt.connect()
                        })
                        .then((server) => {
                            // Set the isConnected variable to true
                            this.bluetoothDevice.isConnected = true;
                            // Get the accelerometer service (if it's not enabled, the error will be caught below)
                            return server.getPrimaryServices();
                        })
                        .then(services => {
                            console.log("Getting characteristics...");
                            let queue = Promise.resolve();
                            services.forEach(service => {
                                console.log("Service: " + service.uuid);
                                switch (service.uuid) {
                                    case ('0000180f-0000-1000-8000-00805f9b34fb'): {
                                        queue = queue.then(_ => service.getCharacteristics().then(characteristics => {
                                            ////console.log("Service: " + service.uuid);
                                            characteristics.forEach(characteristic => {
                                                switch (characteristic.uuid) {
                                                    case ('00002a19-0000-1000-8000-00805f9b34fb'): {
                                                        queue = queue.then(_ => this.getBatteryPercent(characteristic)); break;
                                                    }
                                                }
                                            })
                                        }));
                                    }
                                    case ('0000180a-0000-1000-8000-00805f9b34fb'): {
                                        queue = queue.then(_ => service.getCharacteristics().then(characteristics => {
                                            ////console.log("Service: " + service.uuid);
                                            characteristics.forEach(characteristic => {
                                                console.log("Characteristic: " + characteristic.uuid);
                                                switch (characteristic.uuid) {
                                                    case ('00002a23-0000-1000-8000-00805f9b34fb'): { queue = queue.then(_ => this.getMACAddress(characteristic)); break; }
                                                    case ('00002a24-0000-1000-8000-00805f9b34fb'): { queue = queue.then(_ => this.getModelNum(characteristic)); break; }
                                                    case ('00002a26-0000-1000-8000-00805f9b34fb'): { queue = queue.then(_ => this.getFW(characteristic)); break; }
                                                    case ('00002a27-0000-1000-8000-00805f9b34fb'): { queue = queue.then(_ => this.getHW(characteristic)); break; }
                                                    case ('00002a29-0000-1000-8000-00805f9b34fb'): { queue = queue.then(_ => this.getMfgName(characteristic)); break; }
                                                }
                                            })
                                        }))
                                    }
                                }
                            });
                        })
                        .catch(error => { console.error("ERROR"); });
                }
            },
            //BATTERY
            getBatteryPercent: function (characteristic) {
                return characteristic.readValue().then(value => {
                    this.deviceInfo.battery= value.getUint8(0);
                });
            },
            //DEVICE INFO
            getMACAddress: function (characteristic) {
                let decoder = new TextDecoder('utf-8');
                return characteristic.readValue().then(value => {
                    this.deviceInfo.macAddress = decoder.decode(value);
                });
            },
            getModelNum: function (characteristic) {
                let decoder = new TextDecoder('utf-8');
                return characteristic.readValue().then(value => {
                    this.deviceInfo.modelNum = decoder.decode(value);
                });
            },
            getFW: function (characteristic) {
                let decoder = new TextDecoder('utf-8');
                return characteristic.readValue().then(value => {
                    this.deviceInfo.fw = decoder.decode(value);
                });
            },
            getHW: function (characteristic) {
                let decoder = new TextDecoder('utf-8');
                return characteristic.readValue().then(value => {
                    this.deviceInfo.hw = decoder.decode(value);
                });
            },
            getMfgName: function (characteristic) {
                let decoder = new TextDecoder('utf-8');
                return characteristic.readValue().then(value => {
                    this.deviceInfo.mfgName = decoder.decode(value);
                });
            },

Upon hitting the Connect button, I get this error: localhost/:1 Uncaught (in promise) DOMException: GATT Error Unknown.

How can I fix this?

A few googles says that likely the issue is that the device is unreachable… you could try throwing additional console log messages to figure out where the code is falling down… one inside each of the first two thens would probably point out which part of the function is failing at least…

Just this device is unreachable. The last device has no issues, so what can be done to fix this?

Here is the additional log messages:

Promise.then (async)		
eval	@	UVDetector.vue?e507:131
eval	@	UVDetector.vue?e507:124
Promise.then (async)		
eval	@	UVDetector.vue?e507:122
Promise.then (async)		
eval	@	UVDetector.vue?e507:122
eval	@	UVDetector.vue?e507:106
Promise.then (async)		
getDevice	@	UVDetector.vue?e507:102
onClick._cache.<computed>._cache.<computed>	@	UVDetector.vue?e507:11
callWithErrorHandling	@	runtime-core.esm-bundler.js?d2dd:155
callWithAsyncErrorHandling	@	runtime-core.esm-bundler.js?d2dd:164
invoker	@	runtime-dom.esm-bundler.js?2725:369

One of the offending lines is in here:

                return characteristic.readValue().then(value => {
                    this.deviceInfo.modelNum = decoder.decode(value); <--- OFFENDING LINE
                });

so try catching that then , and dumping tge error object to the console, see if it can give you what the problem is

I did as you did, catching them in each promise as below:

            //BATTERY
            getBatteryPercent: function (characteristic) {
                return characteristic.readValue().then(value => {
                    this.deviceInfo.battery= value.getUint8(0);
                }).catch(error => { console.error("UV DETECTOR BATTERY ERROR: "+error); });
            },

and still got this console:

NotSupportedError: GATT Error Unknown.

It all began from the getBatteryPercent function.

Because of this, it disconnected my device and disrupted the further process.

What if the device that I am provided has a blocklist that doesn’t allow me to view or modify their contents?

Lookup the manufacturer? See if they have a forum.

I did a google for ‘Bluetooth LE UV Detector’ and the first firm that came up ‘Nordic’ had their own tech support community.

I also found what appears to be a more general one called chromforum.

Maybe someone on the relevant forum could point you in the right direction. Firmware etc.

Just a thought.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.