Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: make error codes consistent #1054

Merged
merged 2 commits into from
Dec 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/dialer/dial-request.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const FIFO = require('p-fifo')
const pAny = require('p-any')
// @ts-expect-error setMaxListeners is missing from the types
const { setMaxListeners } = require('events')
const { codes } = require('../errors')

/**
* @typedef {import('libp2p-interfaces/src/connection').Connection} Connection
Expand Down Expand Up @@ -55,7 +56,7 @@ class DialRequest {
const tokens = this.dialer.getTokens(this.addrs.length)
// If no tokens are available, throw
if (tokens.length < 1) {
throw errCode(new Error('No dial tokens available'), 'ERR_NO_DIAL_TOKENS')
throw errCode(new Error('No dial tokens available'), codes.ERR_NO_DIAL_TOKENS)
}

const tokenHolder = new FIFO()
Expand Down
26 changes: 25 additions & 1 deletion src/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,29 @@ exports.codes = {
ERR_TRANSPORT_DIAL_FAILED: 'ERR_TRANSPORT_DIAL_FAILED',
ERR_UNSUPPORTED_PROTOCOL: 'ERR_UNSUPPORTED_PROTOCOL',
ERR_INVALID_MULTIADDR: 'ERR_INVALID_MULTIADDR',
ERR_SIGNATURE_NOT_VALID: 'ERR_SIGNATURE_NOT_VALID'
ERR_SIGNATURE_NOT_VALID: 'ERR_SIGNATURE_NOT_VALID',
ERR_FIND_SELF: 'ERR_FIND_SELF',
ERR_NO_ROUTERS: 'ERR_NO_ROUTERS',
ERR_CONNECTION_NOT_MULTIPLEXED: 'ERR_CONNECTION_NOT_MULTIPLEXED',
ERR_NO_DIAL_TOKENS: 'ERR_NO_DIAL_TOKENS',
ERR_KEYCHAIN_REQUIRED: 'ERR_KEYCHAIN_REQUIRED',
ERR_INVALID_CMS: 'ERR_INVALID_CMS',
ERR_MISSING_KEYS: 'ERR_MISSING_KEYS',
ERR_NO_KEY: 'ERR_NO_KEY',
ERR_INVALID_KEY_NAME: 'ERR_INVALID_KEY_NAME',
ERR_INVALID_KEY_TYPE: 'ERR_INVALID_KEY_TYPE',
ERR_KEY_ALREADY_EXISTS: 'ERR_KEY_ALREADY_EXISTS',
ERR_INVALID_KEY_SIZE: 'ERR_INVALID_KEY_SIZE',
ERR_KEY_NOT_FOUND: 'ERR_KEY_NOT_FOUND',
ERR_OLD_KEY_NAME_INVALID: 'ERR_OLD_KEY_NAME_INVALID',
ERR_NEW_KEY_NAME_INVALID: 'ERR_NEW_KEY_NAME_INVALID',
ERR_PASSWORD_REQUIRED: 'ERR_PASSWORD_REQUIRED',
ERR_PEM_REQUIRED: 'ERR_PEM_REQUIRED',
ERR_CANNOT_READ_KEY: 'ERR_CANNOT_READ_KEY',
ERR_MISSING_PRIVATE_KEY: 'ERR_MISSING_PRIVATE_KEY',
ERR_INVALID_OLD_PASS_TYPE: 'ERR_INVALID_OLD_PASS_TYPE',
ERR_INVALID_NEW_PASS_TYPE: 'ERR_INVALID_NEW_PASS_TYPE',
ERR_INVALID_PASS_LENGTH: 'ERR_INVALID_PASS_LENGTH',
ERR_NOT_IMPLEMENTED: 'ERR_NOT_IMPLEMENTED',
ERR_WRONG_PING_ACK: 'ERR_WRONG_PING_ACK'
}
13 changes: 7 additions & 6 deletions src/keychain/cms.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const { certificateForKey, findAsync } = require('./util')
const errcode = require('err-code')
const { fromString: uint8ArrayFromString } = require('uint8arrays/from-string')
const { toString: uint8ArrayToString } = require('uint8arrays/to-string')
const { codes } = require('../errors')

const privates = new WeakMap()

Expand All @@ -31,7 +32,7 @@ class CMS {
*/
constructor (keychain, dek) {
if (!keychain) {
throw errcode(new Error('keychain is required'), 'ERR_KEYCHAIN_REQUIRED')
throw errcode(new Error('keychain is required'), codes.ERR_KEYCHAIN_REQUIRED)
}

this.keychain = keychain
Expand All @@ -49,7 +50,7 @@ class CMS {
*/
async encrypt (name, plain) {
if (!(plain instanceof Uint8Array)) {
throw errcode(new Error('Plain data must be a Uint8Array'), 'ERR_INVALID_PARAMS')
throw errcode(new Error('Plain data must be a Uint8Array'), codes.ERR_INVALID_PARAMETERS)
}

const key = await this.keychain.findKeyByName(name)
Expand Down Expand Up @@ -81,7 +82,7 @@ class CMS {
*/
async decrypt (cmsData) {
if (!(cmsData instanceof Uint8Array)) {
throw errcode(new Error('CMS data is required'), 'ERR_INVALID_PARAMS')
throw errcode(new Error('CMS data is required'), codes.ERR_INVALID_PARAMETERS)
}

let cms
Expand All @@ -91,7 +92,7 @@ class CMS {
// @ts-ignore not defined
cms = forge.pkcs7.messageFromAsn1(obj)
} catch (/** @type {any} */ err) {
throw errcode(new Error('Invalid CMS: ' + err.message), 'ERR_INVALID_CMS')
throw errcode(new Error('Invalid CMS: ' + err.message), codes.ERR_INVALID_CMS)
}

// Find a recipient whose key we hold. We only deal with recipient certs
Expand Down Expand Up @@ -123,15 +124,15 @@ class CMS {
if (!r) {
// @ts-ignore cms types not defined
const missingKeys = recipients.map(r => r.keyId)
throw errcode(new Error('Decryption needs one of the key(s): ' + missingKeys.join(', ')), 'ERR_MISSING_KEYS', {
throw errcode(new Error('Decryption needs one of the key(s): ' + missingKeys.join(', ')), codes.ERR_MISSING_KEYS, {
missingKeys
})
}

const key = await this.keychain.findKeyById(r.keyId)

if (!key) {
throw errcode(new Error('No key available to decrypto'), 'ERR_NO_KEY')
throw errcode(new Error('No key available to decrypto'), codes.ERR_NO_KEY)
}

const pem = await this.keychain._getPrivateKey(key.name)
Expand Down
49 changes: 25 additions & 24 deletions src/keychain/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const crypto = require('libp2p-crypto')
const { Key } = require('interface-datastore/key')
const CMS = require('./cms')
const errcode = require('err-code')
const { codes } = require('../errors')
const { toString: uint8ArrayToString } = require('uint8arrays/to-string')
const { fromString: uint8ArrayFromString } = require('uint8arrays/from-string')

Expand Down Expand Up @@ -210,21 +211,21 @@ class Keychain {
const self = this

if (!validateKeyName(name) || name === 'self') {
return throwDelayed(errcode(new Error(`Invalid key name '${name}'`), 'ERR_INVALID_KEY_NAME'))
return throwDelayed(errcode(new Error(`Invalid key name '${name}'`), codes.ERR_INVALID_KEY_NAME))
}

if (typeof type !== 'string') {
return throwDelayed(errcode(new Error(`Invalid key type '${type}'`), 'ERR_INVALID_KEY_TYPE'))
return throwDelayed(errcode(new Error(`Invalid key type '${type}'`), codes.ERR_INVALID_KEY_TYPE))
}

const dsname = DsName(name)
const exists = await self.store.has(dsname)
if (exists) return throwDelayed(errcode(new Error(`Key '${name}' already exists`), 'ERR_KEY_ALREADY_EXISTS'))
if (exists) return throwDelayed(errcode(new Error(`Key '${name}' already exists`), codes.ERR_KEY_ALREADY_EXISTS))

switch (type.toLowerCase()) {
case 'rsa':
if (!Number.isSafeInteger(size) || size < 2048) {
return throwDelayed(errcode(new Error(`Invalid RSA key size ${size}`), 'ERR_INVALID_KEY_SIZE'))
return throwDelayed(errcode(new Error(`Invalid RSA key size ${size}`), codes.ERR_INVALID_KEY_SIZE))
}
break
default:
Expand Down Expand Up @@ -297,15 +298,15 @@ class Keychain {
*/
async findKeyByName (name) {
if (!validateKeyName(name)) {
return throwDelayed(errcode(new Error(`Invalid key name '${name}'`), 'ERR_INVALID_KEY_NAME'))
return throwDelayed(errcode(new Error(`Invalid key name '${name}'`), codes.ERR_INVALID_KEY_NAME))
}

const dsname = DsInfoName(name)
try {
const res = await this.store.get(dsname)
return JSON.parse(uint8ArrayToString(res))
} catch (/** @type {any} */ err) {
return throwDelayed(errcode(new Error(`Key '${name}' does not exist. ${err.message}`), 'ERR_KEY_NOT_FOUND'))
return throwDelayed(errcode(new Error(`Key '${name}' does not exist. ${err.message}`), codes.ERR_KEY_NOT_FOUND))
}
}

Expand All @@ -318,7 +319,7 @@ class Keychain {
async removeKey (name) {
const self = this
if (!validateKeyName(name) || name === 'self') {
return throwDelayed(errcode(new Error(`Invalid key name '${name}'`), 'ERR_INVALID_KEY_NAME'))
return throwDelayed(errcode(new Error(`Invalid key name '${name}'`), codes.ERR_INVALID_KEY_NAME))
}
const dsname = DsName(name)
const keyInfo = await self.findKeyByName(name)
Expand All @@ -339,18 +340,18 @@ class Keychain {
async renameKey (oldName, newName) {
const self = this
if (!validateKeyName(oldName) || oldName === 'self') {
return throwDelayed(errcode(new Error(`Invalid old key name '${oldName}'`), 'ERR_OLD_KEY_NAME_INVALID'))
return throwDelayed(errcode(new Error(`Invalid old key name '${oldName}'`), codes.ERR_OLD_KEY_NAME_INVALID))
}
if (!validateKeyName(newName) || newName === 'self') {
return throwDelayed(errcode(new Error(`Invalid new key name '${newName}'`), 'ERR_NEW_KEY_NAME_INVALID'))
return throwDelayed(errcode(new Error(`Invalid new key name '${newName}'`), codes.ERR_NEW_KEY_NAME_INVALID))
}
const oldDsname = DsName(oldName)
const newDsname = DsName(newName)
const oldInfoName = DsInfoName(oldName)
const newInfoName = DsInfoName(newName)

const exists = await self.store.has(newDsname)
if (exists) return throwDelayed(errcode(new Error(`Key '${newName}' already exists`), 'ERR_KEY_ALREADY_EXISTS'))
if (exists) return throwDelayed(errcode(new Error(`Key '${newName}' already exists`), codes.ERR_KEY_ALREADY_EXISTS))

try {
const pem = await self.store.get(oldDsname)
Expand Down Expand Up @@ -379,10 +380,10 @@ class Keychain {
*/
async exportKey (name, password) {
if (!validateKeyName(name)) {
return throwDelayed(errcode(new Error(`Invalid key name '${name}'`), 'ERR_INVALID_KEY_NAME'))
return throwDelayed(errcode(new Error(`Invalid key name '${name}'`), codes.ERR_INVALID_KEY_NAME))
}
if (!password) {
return throwDelayed(errcode(new Error('Password is required'), 'ERR_PASSWORD_REQUIRED'))
return throwDelayed(errcode(new Error('Password is required'), codes.ERR_PASSWORD_REQUIRED))
}

const dsname = DsName(name)
Expand All @@ -409,20 +410,20 @@ class Keychain {
async importKey (name, pem, password) {
const self = this
if (!validateKeyName(name) || name === 'self') {
return throwDelayed(errcode(new Error(`Invalid key name '${name}'`), 'ERR_INVALID_KEY_NAME'))
return throwDelayed(errcode(new Error(`Invalid key name '${name}'`), codes.ERR_INVALID_KEY_NAME))
}
if (!pem) {
return throwDelayed(errcode(new Error('PEM encoded key is required'), 'ERR_PEM_REQUIRED'))
return throwDelayed(errcode(new Error('PEM encoded key is required'), codes.ERR_PEM_REQUIRED))
}
const dsname = DsName(name)
const exists = await self.store.has(dsname)
if (exists) return throwDelayed(errcode(new Error(`Key '${name}' already exists`), 'ERR_KEY_ALREADY_EXISTS'))
if (exists) return throwDelayed(errcode(new Error(`Key '${name}' already exists`), codes.ERR_KEY_ALREADY_EXISTS))

let privateKey
try {
privateKey = await crypto.keys.import(pem, password)
} catch (/** @type {any} */ err) {
return throwDelayed(errcode(new Error('Cannot read the key, most likely the password is wrong'), 'ERR_CANNOT_READ_KEY'))
return throwDelayed(errcode(new Error('Cannot read the key, most likely the password is wrong'), codes.ERR_CANNOT_READ_KEY))
}

let kid
Expand Down Expand Up @@ -457,16 +458,16 @@ class Keychain {
async importPeer (name, peer) {
const self = this
if (!validateKeyName(name)) {
return throwDelayed(errcode(new Error(`Invalid key name '${name}'`), 'ERR_INVALID_KEY_NAME'))
return throwDelayed(errcode(new Error(`Invalid key name '${name}'`), codes.ERR_INVALID_KEY_NAME))
}
if (!peer || !peer.privKey) {
return throwDelayed(errcode(new Error('Peer.privKey is required'), 'ERR_MISSING_PRIVATE_KEY'))
return throwDelayed(errcode(new Error('Peer.privKey is required'), codes.ERR_MISSING_PRIVATE_KEY))
}

const privateKey = peer.privKey
const dsname = DsName(name)
const exists = await self.store.has(dsname)
if (exists) return throwDelayed(errcode(new Error(`Key '${name}' already exists`), 'ERR_KEY_ALREADY_EXISTS'))
if (exists) return throwDelayed(errcode(new Error(`Key '${name}' already exists`), codes.ERR_KEY_ALREADY_EXISTS))

try {
const kid = await privateKey.id()
Expand Down Expand Up @@ -495,15 +496,15 @@ class Keychain {
*/
async _getPrivateKey (name) {
if (!validateKeyName(name)) {
return throwDelayed(errcode(new Error(`Invalid key name '${name}'`), 'ERR_INVALID_KEY_NAME'))
return throwDelayed(errcode(new Error(`Invalid key name '${name}'`), codes.ERR_INVALID_KEY_NAME))
}

try {
const dsname = DsName(name)
const res = await this.store.get(dsname)
return uint8ArrayToString(res)
} catch (/** @type {any} */ err) {
return throwDelayed(errcode(new Error(`Key '${name}' does not exist. ${err.message}`), 'ERR_KEY_NOT_FOUND'))
return throwDelayed(errcode(new Error(`Key '${name}' does not exist. ${err.message}`), codes.ERR_KEY_NOT_FOUND))
}
}

Expand All @@ -515,13 +516,13 @@ class Keychain {
*/
async rotateKeychainPass (oldPass, newPass) {
if (typeof oldPass !== 'string') {
return throwDelayed(errcode(new Error(`Invalid old pass type '${typeof oldPass}'`), 'ERR_INVALID_OLD_PASS_TYPE'))
return throwDelayed(errcode(new Error(`Invalid old pass type '${typeof oldPass}'`), codes.ERR_INVALID_OLD_PASS_TYPE))
}
if (typeof newPass !== 'string') {
return throwDelayed(errcode(new Error(`Invalid new pass type '${typeof newPass}'`), 'ERR_INVALID_NEW_PASS_TYPE'))
return throwDelayed(errcode(new Error(`Invalid new pass type '${typeof newPass}'`), codes.ERR_INVALID_NEW_PASS_TYPE))
}
if (newPass.length < 20) {
return throwDelayed(errcode(new Error(`Invalid pass length ${newPass.length}`), 'ERR_INVALID_PASS_LENGTH'))
return throwDelayed(errcode(new Error(`Invalid pass length ${newPass.length}`), codes.ERR_INVALID_PASS_LENGTH))
}
log('recreating keychain')
const oldDek = privates.get(this).dek
Expand Down
9 changes: 5 additions & 4 deletions src/peer-routing.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const log = Object.assign(debug('libp2p:peer-routing'), {
error: debug('libp2p:peer-routing:err')
})
const errCode = require('err-code')
const errors = require('./errors')
const {
storeAddresses,
uniquePeers,
Expand Down Expand Up @@ -104,11 +105,11 @@ class PeerRouting {
*/
async findPeer (id, options) { // eslint-disable-line require-await
if (!this._routers.length) {
throw errCode(new Error('No peer routers available'), 'NO_ROUTERS_AVAILABLE')
throw errCode(new Error('No peer routers available'), errors.codes.ERR_NO_ROUTERS)
}

if (id.toB58String() === this._peerId.toB58String()) {
throw errCode(new Error('Should not try to find self'), 'ERR_FIND_SELF')
throw errCode(new Error('Should not try to find self'), errors.codes.ERR_FIND_SELF)
}

const output = await pipe(
Expand All @@ -125,7 +126,7 @@ class PeerRouting {
return output
}

throw errCode(new Error('not found'), 'NOT_FOUND')
throw errCode(new Error(errors.messages.NOT_FOUND), errors.codes.ERR_NOT_FOUND)
}

/**
Expand All @@ -139,7 +140,7 @@ class PeerRouting {
*/
async * getClosestPeers (key, options = { timeout: 30e3 }) {
if (!this._routers.length) {
throw errCode(new Error('No peer routers available'), 'NO_ROUTERS_AVAILABLE')
throw errCode(new Error('No peer routers available'), errors.codes.ERR_NO_ROUTERS)
}

if (options.timeout) {
Expand Down
11 changes: 4 additions & 7 deletions src/peer-store/book.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@

const errcode = require('err-code')
const PeerId = require('peer-id')

const {
codes: { ERR_INVALID_PARAMETERS }
} = require('../errors')
const { codes } = require('../errors')

/**
* @param {any} data
Expand Down Expand Up @@ -48,7 +45,7 @@ class Book {
* @param {any[]|any} data
*/
set (peerId, data) {
throw errcode(new Error('set must be implemented by the subclass'), 'ERR_NOT_IMPLEMENTED')
throw errcode(new Error('set must be implemented by the subclass'), codes.ERR_NOT_IMPLEMENTED)
}

/**
Expand Down Expand Up @@ -94,7 +91,7 @@ class Book {
*/
get (peerId) {
if (!PeerId.isPeerId(peerId)) {
throw errcode(new Error('peerId must be an instance of peer-id'), ERR_INVALID_PARAMETERS)
throw errcode(new Error('peerId must be an instance of peer-id'), codes.ERR_INVALID_PARAMETERS)
}

const rec = this.data.get(peerId.toB58String())
Expand All @@ -111,7 +108,7 @@ class Book {
*/
delete (peerId) {
if (!PeerId.isPeerId(peerId)) {
throw errcode(new Error('peerId must be an instance of peer-id'), ERR_INVALID_PARAMETERS)
throw errcode(new Error('peerId must be an instance of peer-id'), codes.ERR_INVALID_PARAMETERS)
}

if (!this.data.delete(peerId.toB58String())) {
Expand Down
4 changes: 2 additions & 2 deletions src/ping/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const log = Object.assign(debug('libp2p:ping'), {
error: debug('libp2p:ping:err')
})
const errCode = require('err-code')

const { codes } = require('../errors')
const crypto = require('libp2p-crypto')
const { pipe } = require('it-pipe')
// @ts-ignore it-buffer has no types exported
Expand Down Expand Up @@ -50,7 +50,7 @@ async function ping (node, peer) {
const end = Date.now()

if (!equals(data, result)) {
throw errCode(new Error('Received wrong ping ack'), 'ERR_WRONG_PING_ACK')
throw errCode(new Error('Received wrong ping ack'), codes.ERR_WRONG_PING_ACK)
}

return end - start
Expand Down
2 changes: 1 addition & 1 deletion src/upgrader.js
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ class Upgrader {
maConn.timeline.upgraded = Date.now()

const errConnectionNotMultiplexed = () => {
throw errCode(new Error('connection is not multiplexed'), 'ERR_CONNECTION_NOT_MULTIPLEXED')
throw errCode(new Error('connection is not multiplexed'), codes.ERR_CONNECTION_NOT_MULTIPLEXED)
}

// Create the connection
Expand Down
Loading