Repository: bitcoinjs/bitcoinjs-lib
Pull request #441 (2015-08-17 22:59:33)

address: consistent errors
This changes gives a more meaningful error for an invalid address,  while also making the exception message checking easier by making the exception format always contain the input value first (last would be fine too).


Patch:
diff --git a/src/address.js b/src/address.js
index 0def957a..879b0893 100644
--- a/src/address.js
+++ b/src/address.js
@@ -4,9 +4,10 @@ var networks = require('./networks')
 var scripts = require('./scripts')
 var types = require('./types')
 
-function fromBase58Check (string) {
-  var payload = base58check.decode(string)
-  if (payload.length !== 21) throw new TypeError('Invalid address length')
+function fromBase58Check (address) {
+  var payload = base58check.decode(address)
+  if (payload.length < 21) throw new TypeError(address + ' is too short')
+  if (payload.length > 21) throw new TypeError(address + ' is too long')
 
   var version = payload.readUInt8(0)
   var hash = payload.slice(1)
@@ -37,7 +38,8 @@ function toOutputScript (address, network) {
   network = network || networks.bitcoin
 
   var payload = base58check.decode(address)
-  if (payload.length !== 21) throw new TypeError('Invalid hash length')
+  if (payload.length < 21) throw new TypeError(address + ' is too short')
+  if (payload.length > 21) throw new TypeError(address + ' is too long')
 
   var version = payload.readUInt8(0)
   var hash = payload.slice(1)


Test patch:
diff --git a/test/address.js b/test/address.js
index 48d8ba5c..541fb88a 100644
--- a/test/address.js
+++ b/test/address.js
@@ -20,17 +20,17 @@ describe('Address', function () {
     })
 
     fixtures.invalid.fromBase58Check.forEach(function (f) {
-      it('throws on ' + f.description, function () {
+      it('throws on ' + f.exception, function () {
         assert.throws(function () {
-          Address.fromBase58Check(f.base58check)
-        }, new RegExp(f.exception))
+          Address.fromBase58Check(f.address)
+        }, new RegExp(f.address + ' ' + f.exception))
       })
     })
   })
 
   describe('fromOutputScript', function () {
     fixtures.valid.forEach(function (f) {
-      it('parses ' + f.script + ' (' + f.network + ')', function () {
+      it('parses ' + f.script.slice(0, 30) + '... (' + f.network + ')', function () {
         var script = Script.fromASM(f.script)
         var address = Address.fromOutputScript(script, networks[f.network])
 
@@ -39,12 +39,12 @@ describe('Address', function () {
     })
 
     fixtures.invalid.fromOutputScript.forEach(function (f) {
-      it('throws when ' + f.description, function () {
+      it('throws when ' + f.script.slice(0, 30) + '... ' + f.exception, function () {
         var script = Script.fromASM(f.script)
 
         assert.throws(function () {
           Address.fromOutputScript(script)
-        }, new RegExp(f.description))
+        }, new RegExp(f.script + ' ' + f.exception))
       })
     })
   })
@@ -63,7 +63,7 @@ describe('Address', function () {
     fixtures.valid.forEach(function (f) {
       var network = networks[f.network]
 
-      it('exports ' + f.script + '(' + f.network + ')', function () {
+      it('exports ' + f.script.slice(0, 30) + '... (' + f.network + ')', function () {
         var script = Address.toOutputScript(f.base58check, network)
 
         assert.strictEqual(script.toASM(), f.script)
@@ -71,10 +71,10 @@ describe('Address', function () {
     })
 
     fixtures.invalid.toOutputScript.forEach(function (f) {
-      it('throws when ' + f.description, function () {
+      it('throws when ' + f.exception, function () {
         assert.throws(function () {
           Address.toOutputScript(f.address)
-        }, new RegExp(f.description))
+        }, new RegExp(f.address + ' ' + f.exception))
       })
     })
   })
diff --git a/test/fixtures/address.json b/test/fixtures/address.json
index 02c36a14..be32141e 100644
--- a/test/fixtures/address.json
+++ b/test/fixtures/address.json
@@ -32,33 +32,31 @@
   "invalid": {
     "fromBase58Check": [
       {
-        "description": "hash too short",
-        "base58check": "7SeEnXWPaCCALbVrTnszCVGfRU8cGfx",
-        "exception": "Invalid address length"
+        "address": "7SeEnXWPaCCALbVrTnszCVGfRU8cGfx",
+        "exception": "is too short"
       },
       {
-        "description": "hash too long",
-        "base58check": "j9ywUkWg2fTQrouxxh5rSZhRvrjMkEUfuiKe",
-        "exception": "Invalid address length"
+        "address": "j9ywUkWg2fTQrouxxh5rSZhRvrjMkEUfuiKe",
+        "exception": "is too long"
       }
     ],
     "fromOutputScript": [
       {
-        "description": "has no matching Address",
+        "exception": "has no matching Address",
         "script": "031f1e68f82112b373f0fe980b3a89d212d2b5c01fb51eb25acb8b4c4b4299ce95 OP_CHECKSIG"
       },
       {
-        "description": "has no matching Address",
+        "exception": "has no matching Address",
         "script": "OP_TRUE 032487c2a32f7c8d57d2a93906a6457afd00697925b0e6e145d89af6d3bca33016 02308673d16987eaa010e540901cc6fe3695e758c19f46ce604e174dac315e685a OP_2 OP_CHECKMULTISIG"
       },
       {
-        "description": "has no matching Address",
+        "exception": "has no matching Address",
         "script": "OP_RETURN 06deadbeef03f895a2ad89fb6d696497af486cb7c644a27aa568c7a18dd06113401115185474"
       }
     ],
     "toOutputScript": [
       {
-        "description": "24kPZCmVgzfkpGdXExy56234MRHrsqQxNWE has no matching Script",
+        "exception": "has no matching Script",
         "address": "24kPZCmVgzfkpGdXExy56234MRHrsqQxNWE"
       }
     ]