Skip to content
This repository was archived by the owner on Mar 23, 2023. It is now read-only.

feat: add basic error codes and update test #8

Merged
merged 6 commits into from
Oct 1, 2018
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
32 changes: 0 additions & 32 deletions .travis.yml

This file was deleted.

29 changes: 0 additions & 29 deletions appveyor.yml

This file was deleted.

15 changes: 0 additions & 15 deletions circle.yml

This file was deleted.

17 changes: 11 additions & 6 deletions examples/full-s3-repo/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
const IPFS = require('ipfs')
const Repo = require('ipfs-repo')
const S3 = require('aws-sdk').S3
const S3Store = require('../../src')
const S3Store = require('datastore-s3')
const S3Lock = require('./s3-lock')

// Initialize the AWS S3 instance
Expand Down Expand Up @@ -38,9 +38,15 @@ const repo = new Repo('/tmp/test/.ipfs', {

// Create a new IPFS node with our S3 backed Repo
let node = new IPFS({
repo
repo,
config: {
Discovery: { MDNS: { Enabled: false }, webRTCStar: { Enabled: false } },
Bootstrap: []
}
})

console.log('Start the node')

// Test out the repo by sending and fetching some data
node.on('ready', () => {
console.log('Ready')
Expand All @@ -51,8 +57,8 @@ node.on('ready', () => {
// Once we have the version, let's add a file to IPFS
.then(() => {
return node.files.add({
path: 'hello.txt',
content: Buffer.from('Hello World 101')
path: 'data.txt',
content: Buffer.from(require('crypto').randomBytes(1024 * 25))
})
})
// Log out the added files metadata and cat the file from IPFS
Expand All @@ -62,8 +68,7 @@ node.on('ready', () => {
})
// Print out the files contents to console
.then((data) => {
console.log('\nFetched file content:')
process.stdout.write(data)
console.log(`\nFetched file content containing ${data.byteLength} bytes`)
})
// Log out the error, if there is one
.catch((err) => {
Expand Down
9 changes: 5 additions & 4 deletions examples/full-s3-repo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@
"author": "",
"license": "ISC",
"dependencies": {
"async": "^2.6.0",
"aws-sdk": "^2.220.1",
"ipfs": "^0.28.2",
"ipfs-repo": "^0.20.0"
"async": "^2.6.1",
"aws-sdk": "^2.313.0",
"datastore-s3": "../../",
"ipfs": "~0.32.3",
"ipfs-repo": "~0.24.0"
}
}
2 changes: 1 addition & 1 deletion examples/full-s3-repo/s3-lock.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class S3Lock {
*/
locked (dir, callback) {
this.s3.get(this.getLockfilePath(dir), (err, data) => {
if (err && err.message.match(/not found/)) {
if (err && err.code === 'ERR_NOT_FOUND') {
return callback(null, false)
} else if (err) {
return callback(err)
Expand Down
20 changes: 10 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,20 @@
},
"homepage": "https://github.com/ipfs/js-datastore-s3#readme",
"dependencies": {
"async": "^2.6.0",
"datastore-core": "^0.4.0",
"interface-datastore": "^0.4.2",
"pull-defer": "^0.2.2",
"pull-stream": "^3.6.7",
"upath": "^1.0.5"
"async": "^2.6.1",
"datastore-core": "~0.5.0",
"interface-datastore": "~0.5.0",
"pull-defer": "~0.2.3",
"pull-stream": "^3.6.9",
"upath": "^1.1.0"
},
"devDependencies": {
"aegir": "^13.0.6",
"aws-sdk": "^2.219.1",
"aegir": "^15.2.0",
"aws-sdk": "^2.316.0",
"chai": "^4.1.2",
"dirty-chai": "^2.0.1",
"flow-bin": "^0.69.0",
"flow-typed": "^2.4.0",
"flow-bin": "~0.81.0",
"flow-typed": "^2.5.1",
"stand-in": "^4.2.0"
},
"contributors": [
Expand Down
28 changes: 19 additions & 9 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ const each = require('async/each')
const waterfall = require('async/series')
const asyncFilter = require('interface-datastore').utils.asyncFilter
const asyncSort = require('interface-datastore').utils.asyncSort
const Key = require('interface-datastore').Key

const IDatastore = require('interface-datastore')
const Key = IDatastore.Key
const Errors = IDatastore.Errors

const Deferred = require('pull-defer')
const pull = require('pull-stream')
Expand Down Expand Up @@ -90,13 +93,15 @@ class S3Datastore {
Body: val
}, (err, data) => {
if (err && err.code === 'NoSuchBucket' && this.createIfMissing) {
this.opts.s3.createBucket({}, (err) => {
return this.opts.s3.createBucket({}, (err) => {
if (err) return callback(err)
setImmediate(() => this.put(key, val, callback))
})
} else {
callback(err)
} else if (err) {
return callback(Errors.dbWriteFailedError(err))
}

callback()
})
}

Expand All @@ -112,8 +117,7 @@ class S3Datastore {
Key: this._getFullKey(key)
}, (err, data) => {
if (err && err.statusCode === 404) {
// TODO: Cleanup across repos https://github.com/ipfs/js-ipfs/blob/master/src/core/boot.js#L43
return callback(new Error('not found'))
return callback(Errors.notFoundError(err))
} else if (err) {
return callback(err)
}
Expand Down Expand Up @@ -154,8 +158,11 @@ class S3Datastore {
delete (key /* : Key */, callback /* : Callback<void> */) /* : void */ {
this.opts.s3.deleteObject({
Key: this._getFullKey(key)
}, (err, data) => {
callback(err)
}, (err) => {
if (err) {
return callback(Errors.dbDeleteFailedError(err))
}
callback()
})
}

Expand Down Expand Up @@ -346,7 +353,10 @@ class S3Datastore {
return this.put(new Key('/', false), Buffer.from(''), callback)
}

callback(err)
if (err) {
return callback(Errors.dbOpenFailedError(err))
}
callback()
})
}

Expand Down
73 changes: 69 additions & 4 deletions test/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ describe('S3Datastore', () => {

store.put(new Key('/z/key'), Buffer.from('test data'), done)
})
it('should create the bucket when missing if createIfMissing is true', (done) => {
it('should not create the bucket when missing if createIfMissing is false', (done) => {
const s3 = new S3({ params: { Bucket: 'my-ipfs-bucket' } })
const store = new S3Store('.ipfs/datastore', { s3, createIfMissing: false })

Expand All @@ -95,9 +95,22 @@ describe('S3Datastore', () => {

store.put(new Key('/z/key'), Buffer.from('test data'), (err) => {
expect(bucketCreated).to.equal(false)
expect(err).to.deep.equal({
code: 'NoSuchBucket'
})
expect(err).to.have.property('code', 'ERR_DB_WRITE_FAILED')
done()
})
})
it('should return a standard error when the put fails', (done) => {
const s3 = new S3({ params: { Bucket: 'my-ipfs-bucket' } })
const store = new S3Store('.ipfs/datastore', { s3 })

standin.replace(s3, 'upload', function (stand, params, callback) {
expect(params.Key).to.equal('.ipfs/datastore/z/key')
stand.restore()
callback(new Error('bad things happened'))
})

store.put(new Key('/z/key'), Buffer.from('test data'), (err) => {
expect(err.code).to.equal('ERR_DB_WRITE_FAILED')
done()
})
})
Expand All @@ -116,6 +129,58 @@ describe('S3Datastore', () => {

store.get(new Key('/z/key'), done)
})
it('should return a standard not found error code if the key isnt found', (done) => {
const s3 = new S3({ params: { Bucket: 'my-ipfs-bucket' } })
const store = new S3Store('.ipfs/datastore', { s3 })

standin.replace(s3, 'getObject', function (stand, params, callback) {
expect(params.Key).to.equal('.ipfs/datastore/z/key')
stand.restore()
let error = new Error('not found')
error.statusCode = 404
callback(error)
})

store.get(new Key('/z/key'), (err) => {
expect(err.code).to.equal('ERR_NOT_FOUND')
done()
})
})
})

describe('delete', () => {
it('should return a standard delete error if deletion fails', (done) => {
const s3 = new S3({ params: { Bucket: 'my-ipfs-bucket' } })
const store = new S3Store('.ipfs/datastore', { s3 })

standin.replace(s3, 'deleteObject', function (stand, params, callback) {
expect(params.Key).to.equal('.ipfs/datastore/z/key')
stand.restore()
callback(new Error('bad things'))
})

store.delete(new Key('/z/key'), (err) => {
expect(err.code).to.equal('ERR_DB_DELETE_FAILED')
done()
})
})
})

describe('open', () => {
it('should return a standard open error if the head request fails with an unknown error', (done) => {
const s3 = new S3({ params: { Bucket: 'my-ipfs-bucket' } })
const store = new S3Store('.ipfs/datastore', { s3 })

standin.replace(s3, 'headObject', function (stand, _, callback) {
stand.restore()
callback(new Error('unknown'))
})

store.open((err) => {
expect(err.code).to.equal('ERR_DB_OPEN_FAILED')
done()
})
})
})

describe('interface-datastore', () => {
Expand Down