From 04e33460864461aff1b003770cb80424d61cbc4b Mon Sep 17 00:00:00 2001 From: Chris Troutner Date: Wed, 4 Feb 2026 12:54:40 -0700 Subject: [PATCH] fix(error handling): Improved error handling. Thowing errors, not objects --- package.json | 2 +- src/blockchain.js | 135 +++++++++++++++++++++++---------- src/dsproof.js | 7 +- src/electrumx.js | 52 +++++++++---- test/integration/blockchain.js | 12 +-- test/integration/electrumx.js | 23 +++--- test/unit/blockchain.js | 2 +- 7 files changed, 158 insertions(+), 75 deletions(-) diff --git a/package.json b/package.json index f1e0a28..3a4979e 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "test:integration:fullstack:free": "export RESTURL=https://bch.fullstack.cash/v6 && mocha --timeout 60000 test/integration/", "test:integration:fullstack:x402": "export RESTURL=https://x402-bch.fullstack.cash/v6 && export BCHJSWIF=L1eYaneXDDXy8VDig4Arwe8wYHbhtsA5wuQvwsKwhaYeneoZuKG4 && mocha --timeout 120000 test/integration/", "test:integration:fullstack:auth": "export RESTURL=http://dev.fullstack.cash/v6 && export BCHJSBEARERTOKEN=test01 && mocha --timeout 30000 test/integration/", - "test:integration:local:noauth": "export RESTURL=http://localhost:5942/v6 && mocha --timeout 30000 test/integration/", + "test:integration:local:noauth": "export RESTURL=http://192.168.1.65:5942/v6 && mocha --timeout 30000 test/integration/", "test:integration:local:auth": "export RESTURL=http://192.168.1.115:5942/v6 && export BCHJSBEARERTOKEN=temp01 && mocha --timeout 30000 test/integration/", "test:integration:local:x402": "export RESTURL=http://localhost:5942/v6 && export BCHJSWIF=L1eYaneXDDXy8VDig4Arwe8wYHbhtsA5wuQvwsKwhaYeneoZuKG4 && mocha --timeout 1200000 test/integration/", "test:integration:decatur": "export RESTURL=http://192.168.1.65:5942/v6 && mocha --timeout 30000 test/integration/", diff --git a/src/blockchain.js b/src/blockchain.js index f226ffd..78b9b86 100644 --- a/src/blockchain.js +++ b/src/blockchain.js @@ -47,8 +47,11 @@ class Blockchain { ) return response.data } catch (error) { - if (error.response && error.response.data) throw error.response.data - else throw error + if (error.response && error.response.data) { + const errorData = error.response.data + const errorMessage = typeof errorData === 'string' ? errorData : (errorData.error || errorData.message || JSON.stringify(errorData)) + throw new Error(errorMessage) + } else throw error } } @@ -105,8 +108,11 @@ class Blockchain { ) return response.data } catch (error) { - if (error.response && error.response.data) throw error.response.data - else throw error + if (error.response && error.response.data) { + const errorData = error.response.data + const errorMessage = typeof errorData === 'string' ? errorData : (errorData.error || errorData.message || JSON.stringify(errorData)) + throw new Error(errorMessage) + } else throw error } } @@ -155,8 +161,11 @@ class Blockchain { ) return response.data } catch (error) { - if (error.response && error.response.data) throw error.response.data - else throw error + if (error.response && error.response.data) { + const errorData = error.response.data + const errorMessage = typeof errorData === 'string' ? errorData : (errorData.error || errorData.message || JSON.stringify(errorData)) + throw new Error(errorMessage) + } else throw error } } @@ -189,8 +198,11 @@ class Blockchain { console.log('Error in bch-js/blockchain.js/getBlockCount()') console.log('blockchain.js restURL: ', this.restURL) - if (error.response && error.response.data) throw error.response.data - else throw error + if (error.response && error.response.data) { + const errorData = error.response.data + const errorMessage = typeof errorData === 'string' ? errorData : (errorData.error || errorData.message || JSON.stringify(errorData)) + throw new Error(errorMessage) + } else throw error } } @@ -222,8 +234,11 @@ class Blockchain { ) return response.data } catch (error) { - if (error.response && error.response.data) throw error.response.data - else throw error + if (error.response && error.response.data) { + const errorData = error.response.data + const errorMessage = typeof errorData === 'string' ? errorData : (errorData.error || errorData.message || JSON.stringify(errorData)) + throw new Error(errorMessage) + } else throw error } } @@ -287,10 +302,13 @@ class Blockchain { throw new Error('Input hash must be a string or array of strings.') } catch (error) { - console.log('Error in bch-js/blockchain.js/getBlockHeader() error: ', error) + // console.log('Error in bch-js/blockchain.js/getBlockHeader() error: ', error) - if (error.response && error.response.data) throw error.response.data - else throw error + if (error.response && error.response.data) { + const errorData = error.response.data + const errorMessage = typeof errorData === 'string' ? errorData : (errorData.error || errorData.message || JSON.stringify(errorData)) + throw new Error(errorMessage) + } else throw error } } @@ -332,8 +350,11 @@ class Blockchain { ) return response.data } catch (error) { - if (error.response && error.response.data) throw error.response.data - else throw error + if (error.response && error.response.data) { + const errorData = error.response.data + const errorMessage = typeof errorData === 'string' ? errorData : (errorData.error || errorData.message || JSON.stringify(errorData)) + throw new Error(errorMessage) + } else throw error } } @@ -364,8 +385,11 @@ class Blockchain { ) return response.data } catch (error) { - if (error.response && error.response.data) throw error.response.data - else throw error + if (error.response && error.response.data) { + const errorData = error.response.data + const errorMessage = typeof errorData === 'string' ? errorData : (errorData.error || errorData.message || JSON.stringify(errorData)) + throw new Error(errorMessage) + } else throw error } } @@ -380,8 +404,11 @@ class Blockchain { ) return response.data } catch (error) { - if (error.response && error.response.data) throw error.response.data - else throw error + if (error.response && error.response.data) { + const errorData = error.response.data + const errorMessage = typeof errorData === 'string' ? errorData : (errorData.error || errorData.message || JSON.stringify(errorData)) + throw new Error(errorMessage) + } else throw error } } @@ -395,8 +422,11 @@ class Blockchain { ) return response.data } catch (error) { - if (error.response && error.response.data) throw error.response.data - else throw error + if (error.response && error.response.data) { + const errorData = error.response.data + const errorMessage = typeof errorData === 'string' ? errorData : (errorData.error || errorData.message || JSON.stringify(errorData)) + throw new Error(errorMessage) + } else throw error } } @@ -507,8 +537,11 @@ class Blockchain { throw new Error('Input must be a string or array of strings.') } catch (error) { - if (error.response && error.response.data) throw error.response.data - else throw error + if (error.response && error.response.data) { + const errorData = error.response.data + const errorMessage = typeof errorData === 'string' ? errorData : (errorData.error || errorData.message || JSON.stringify(errorData)) + throw new Error(errorMessage) + } else throw error } } @@ -543,8 +576,11 @@ class Blockchain { ) return response.data } catch (error) { - if (error.response && error.response.data) throw error.response.data - else throw error + if (error.response && error.response.data) { + const errorData = error.response.data + const errorMessage = typeof errorData === 'string' ? errorData : (errorData.error || errorData.message || JSON.stringify(errorData)) + throw new Error(errorMessage) + } else throw error } } @@ -590,8 +626,11 @@ class Blockchain { ) return response.data } catch (error) { - if (error.response && error.response.data) throw error.response.data - else throw error + if (error.response && error.response.data) { + const errorData = error.response.data + const errorMessage = typeof errorData === 'string' ? errorData : (errorData.error || errorData.message || JSON.stringify(errorData)) + throw new Error(errorMessage) + } else throw error } } @@ -644,8 +683,11 @@ class Blockchain { return response.data } catch (error) { - if (error.response && error.response.data) throw error.response.data - else throw error + if (error.response && error.response.data) { + const errorData = error.response.data + const errorMessage = typeof errorData === 'string' ? errorData : (errorData.error || errorData.message || JSON.stringify(errorData)) + throw new Error(errorMessage) + } else throw error } } @@ -711,8 +753,11 @@ class Blockchain { throw new Error('Input must be a string or array of strings.') } catch (error) { - if (error.response && error.response.data) throw error.response.data - else throw error + if (error.response && error.response.data) { + const errorData = error.response.data + const errorMessage = typeof errorData === 'string' ? errorData : (errorData.error || errorData.message || JSON.stringify(errorData)) + throw new Error(errorMessage) + } else throw error } } @@ -724,8 +769,11 @@ class Blockchain { ) return response.data } catch (error) { - if (error.response && error.response.data) throw error.response.data - else throw error + if (error.response && error.response.data) { + const errorData = error.response.data + const errorMessage = typeof errorData === 'string' ? errorData : (errorData.error || errorData.message || JSON.stringify(errorData)) + throw new Error(errorMessage) + } else throw error } } @@ -737,8 +785,11 @@ class Blockchain { ) return response.data } catch (error) { - if (error.response && error.response.data) throw error.response.data - else throw error + if (error.response && error.response.data) { + const errorData = error.response.data + const errorMessage = typeof errorData === 'string' ? errorData : (errorData.error || errorData.message || JSON.stringify(errorData)) + throw new Error(errorMessage) + } else throw error } } @@ -750,8 +801,11 @@ class Blockchain { ) return response.data } catch (error) { - if (error.response && error.response.data) throw error.response.data - else throw error + if (error.response && error.response.data) { + const errorData = error.response.data + const errorMessage = typeof errorData === 'string' ? errorData : (errorData.error || errorData.message || JSON.stringify(errorData)) + throw new Error(errorMessage) + } else throw error } } @@ -818,8 +872,11 @@ class Blockchain { throw new Error('Input must be a string or array of strings.') } catch (error) { - if (error.response && error.response.data) throw error.response.data - else throw error + if (error.response && error.response.data) { + const errorData = error.response.data + const errorMessage = typeof errorData === 'string' ? errorData : (errorData.error || errorData.message || JSON.stringify(errorData)) + throw new Error(errorMessage) + } else throw error } } } diff --git a/src/dsproof.js b/src/dsproof.js index c6638a0..d9103a7 100644 --- a/src/dsproof.js +++ b/src/dsproof.js @@ -62,8 +62,11 @@ class DSProof { ) return response.data } catch (error) { - if (error.response && error.response.data) throw error.response.data - else throw error + if (error.response && error.response.data) { + const errorData = error.response.data + const errorMessage = typeof errorData === 'string' ? errorData : (errorData.error || errorData.message || JSON.stringify(errorData)) + throw new Error(errorMessage) + } else throw error } } } diff --git a/src/electrumx.js b/src/electrumx.js index e6a876d..e4a42cc 100644 --- a/src/electrumx.js +++ b/src/electrumx.js @@ -120,8 +120,11 @@ class ElectrumX { throw new Error('Input address must be a string or array of strings.') } catch (error) { - if (error.response && error.response.data) throw error.response.data - else throw error + if (error.response && error.response.data) { + const errorData = error.response.data + const errorMessage = typeof errorData === 'string' ? errorData : (errorData.error || errorData.message || JSON.stringify(errorData)) + throw new Error(errorMessage) + } else throw error } } @@ -204,8 +207,11 @@ class ElectrumX { throw new Error('Input address must be a string or array of strings.') } catch (error) { - if (error.response && error.response.data) throw error.response.data - else throw error + if (error.response && error.response.data) { + const errorData = error.response.data + const errorMessage = typeof errorData === 'string' ? errorData : (errorData.error || errorData.message || JSON.stringify(errorData)) + throw new Error(errorMessage) + } else throw error } } @@ -305,8 +311,11 @@ class ElectrumX { throw new Error('Input address must be a string or array of strings.') } catch (error) { // console.log('Error in transactions(): ', error) - if (error.response && error.response.data) throw error.response.data - else throw error + if (error.response && error.response.data) { + const errorData = error.response.data + const errorMessage = typeof errorData === 'string' ? errorData : (errorData.error || errorData.message || JSON.stringify(errorData)) + throw new Error(errorMessage) + } else throw error } } @@ -397,8 +406,11 @@ class ElectrumX { throw new Error('Input address must be a string or array of strings.') } catch (error) { - if (error.response && error.response.data) throw error.response.data - else throw error + if (error.response && error.response.data) { + const errorData = error.response.data + const errorMessage = typeof errorData === 'string' ? errorData : (errorData.error || errorData.message || JSON.stringify(errorData)) + throw new Error(errorMessage) + } else throw error } } @@ -453,9 +465,13 @@ class ElectrumX { } catch (error) { // console.log("error: ", error) if (error.response && error.response.data) { - if (error.response && error.response.data) { - throw new Error(error.response.data.error) - } else throw error.response.data + const errorData = error.response.data + if (errorData.error) { + throw new Error(errorData.error) + } else { + const errorMessage = typeof errorData === 'string' ? errorData : (errorData.message || JSON.stringify(errorData)) + throw new Error(errorMessage) + } } else { throw error } @@ -555,8 +571,11 @@ class ElectrumX { throw new Error('Input txId must be a string or array of strings.') } catch (error) { - if (error.response && error.response.data) throw error.response.data - else throw error + if (error.response && error.response.data) { + const errorData = error.response.data + const errorMessage = typeof errorData === 'string' ? errorData : (errorData.error || errorData.message || JSON.stringify(errorData)) + throw new Error(errorMessage) + } else throw error } } @@ -595,8 +614,11 @@ class ElectrumX { throw new Error('Input txHex must be a string.') } catch (error) { - if (error.response && error.response.data) throw error.response.data - else throw error + if (error.response && error.response.data) { + const errorData = error.response.data + const errorMessage = typeof errorData === 'string' ? errorData : (errorData.error || errorData.message || JSON.stringify(errorData)) + throw new Error(errorMessage) + } else throw error } } diff --git a/test/integration/blockchain.js b/test/integration/blockchain.js index db36731..56f58d7 100644 --- a/test/integration/blockchain.js +++ b/test/integration/blockchain.js @@ -103,8 +103,8 @@ describe('#blockchain', () => { console.log(`result: ${util.inspect(result)}`) assert.equal(true, false, 'Unexpected result!') } catch (err) { - assert.hasAnyKeys(err, ['error']) - assert.include(err.error, 'Array too large') + assert.instanceOf(err, Error) + assert.include(err.message, 'Array too large') } }) }) @@ -171,8 +171,8 @@ describe('#blockchain', () => { assert.equal(true, false, 'Unexpected result!') } catch (err) { // console.log(`err: ${util.inspect(err)}`) - assert.hasAnyKeys(err, ['error']) - assert.include(err.error, 'Transaction not in mempool') + assert.instanceOf(err, Error) + assert.include(err.message, 'Transaction not in mempool') } }) }) @@ -241,8 +241,8 @@ describe('#blockchain', () => { console.log(`result: ${util.inspect(result)}`) assert.equal(true, false, 'Unexpected result!') } catch (err) { - assert.hasAnyKeys(err, ['error']) - assert.include(err.error, 'Array too large') + assert.instanceOf(err, Error) + assert.include(err.message, 'Array too large') } }) }) diff --git a/test/integration/electrumx.js b/test/integration/electrumx.js index 005f7cf..17f1142 100644 --- a/test/integration/electrumx.js +++ b/test/integration/electrumx.js @@ -73,8 +73,8 @@ describe('#ElectrumX', () => { // console.log(`result: ${util.inspect(result)}`) assert.equal(true, false, 'Unexpected result!') } catch (err) { - assert.hasAnyKeys(err, ['error']) - assert.include(err.error, 'Array too large') + assert.instanceOf(err, Error) + assert.include(err.message, 'Array too large') } }) }) @@ -129,8 +129,8 @@ describe('#ElectrumX', () => { assert.equal(true, false, 'Unexpected result!') } catch (err) { - assert.hasAnyKeys(err, ['error']) - assert.include(err.error, 'Array too large') + assert.instanceOf(err, Error) + assert.include(err.message, 'Array too large') } }) }) @@ -187,8 +187,8 @@ describe('#ElectrumX', () => { assert.equal(true, false, 'Unexpected result!') } catch (err) { - assert.hasAnyKeys(err, ['error']) - assert.include(err.error, 'Array too large') + assert.instanceOf(err, Error) + assert.include(err.message, 'Array too large') } }) }) @@ -250,8 +250,8 @@ describe('#ElectrumX', () => { // console.log(`result: ${util.inspect(result)}`) assert.equal(true, false, 'Unexpected result!') } catch (err) { - assert.hasAnyKeys(err, ['error']) - assert.include(err.error, 'Array too large') + assert.instanceOf(err, Error) + assert.include(err.message, 'Array too large') } }) }) @@ -345,8 +345,8 @@ describe('#ElectrumX', () => { // console.log(`result: ${util.inspect(result)}`) assert.equal(true, false, 'Unexpected result!') } catch (err) { - assert.hasAnyKeys(err, ['error']) - assert.include(err.error, 'Array too large') + assert.instanceOf(err, Error) + assert.include(err.message, 'Array too large') } }) }) @@ -359,8 +359,9 @@ describe('#ElectrumX', () => { try { await bchjs.Electrumx.broadcast(txHex) } catch (err) { + // console.error('err: ', err) assert.include( - err.error, + err.message, 'the transaction was rejected by network rules' ) } diff --git a/test/unit/blockchain.js b/test/unit/blockchain.js index 7552302..3101086 100644 --- a/test/unit/blockchain.js +++ b/test/unit/blockchain.js @@ -93,7 +93,7 @@ describe('#Blockchain', () => { await bchjs.Blockchain.getBlock(blockhash) assert2.fail('Unexpected result') } catch (err) { - assert2.include(err, 'Test Error') + assert2.include(err.message, 'Test Error') } }) })