Commit a6f78461 by Alex MacCaw

Remove pending API - turn Queued into an exception

parent cac6f0d1
......@@ -12,7 +12,7 @@ $ npm install clearbit
```
```js
var clearbit = require('clearbit')('api_key');
// or
// or
var Client = require('clearbit').Client;
var clearbit = new Client({key: 'api_key'});
```
......@@ -26,13 +26,13 @@ var clearbit = new Client({key: 'api_key'});
* `webhook_id` *String*: Custom identifier for the webhook request
* `subscribe` *Boolean*: Set to `true` to subscribe to the changes
* `company` *Boolean*: Set to `true` to include a company lookup on the email’s domain name in the response
* `stream` *Boolean*: Set to `true` to use the [streaming API](https://clearbit.co/docs?shell#streaming) instead of webhooks
* `stream` *Boolean*: Set to `true` to use the [streaming API](https://clearbit.co/docs?shell#streaming) instead of webhooks
```js
var Person = clearbit.Person;
Person.find({email: 'email@domain.com'})
.then(function (person) {
if (!person.pending()) {
if (!person.isPending()) {
console.log('Name: ', person.name.fullName);
}
})
......@@ -44,21 +44,18 @@ Person.find({email: 'email@domain.com'})
});
```
#### `person.pending()` -> `Boolean`
If Clearbit responds with a `202` status indicating that lookup has been queued, `person.pending` returns `true`.
### Company
#### `Company.find(options)` -> `Promise`
* `domain` *String*: The company domain to look up **(required)**
* `webhook_id` *String*: Custom identifier for the webhook request
* `stream` *Boolean*: Set to `true` to use the [streaming API](https://clearbit.co/docs?shell#streaming) instead of webhooks
* `stream` *Boolean*: Set to `true` to use the [streaming API](https://clearbit.co/docs?shell#streaming) instead of webhooks
```js
var Company = clearbit.Company;
Company.find({domain: 'www.uber.com'})
.then(function (company) {
if (!company.pending()) {
if (!company.isPending()) {
console.log('Name: ', company.name);
}
})
......@@ -70,8 +67,18 @@ Company.find({domain: 'www.uber.com'})
});
```
#### `company.pending()` -> `Boolean`
If Clearbit responds with a `202` status indicating that lookup has been queued, `company.pending` returns `true`.
### Queued Handling
If Clearbit responds with a `202` status indicating that lookup has been queued, then a `QueuedError` will be thrown. You can catch this like so:
```js
Person.find({email: 'notqueued@example.com'})
.catch(Person.QueuedError, function () {
// Record has been queued
})
```
If long-lived requests are not a problem for you you can avoid queuing errors by using our streaming API.
### Error Handling
Lookups return [Bluebird](https://github.com/petkaantonov/bluebird) promises. Any status code >=400 will trigger an error, including lookups than do not return a result. You can easily filter out unknown records from true errors using [Bluebird's error class matching](https://github.com/petkaantonov/bluebird/blob/master/API.md#catchfunction-errorclassfunction-predicate-function-handler---promise):
......
......@@ -17,6 +17,7 @@ function ClearbitClient (config) {
this.Person = require('./person')(this);
this.Company = require('./company')(this);
this.PersonCompany = require('./person_company')(this);
}
var base = 'https://%s%s.clearbit.co/v%s';
......@@ -66,7 +67,7 @@ ClearbitClient.prototype.request = function (options) {
)
.bind(this)
.spread(function (response, body) {
if (response.statusCode >= 400) {
if (response.statusCode == 202 || response.statusCode >= 400) {
var message = body.error ? body.error.message : http.STATUS_CODES[response.statusCode] || 'Unknown';
throw _.extend(new this.ClearbitError(message), {
type: body.error ? body.error.type : 'unknown',
......
......@@ -10,8 +10,6 @@ module.exports = function (client) {
_.extend(this, data);
}
Company.prototype.pending = utils.pending;
Company.find = Promise.method(function (options) {
assert(options && options.domain, 'A domain must be provided');
return this.client.request(_.extend({
......@@ -20,6 +18,9 @@ module.exports = function (client) {
}, options))
.bind(this)
.then(utils.cast)
.catch(utils.isQueued, function () {
throw new this.QueuedError('Company lookup queued');
})
.catch(utils.isUnknownRecord, function () {
throw new this.NotFoundError('Company not found');
});
......@@ -27,6 +28,7 @@ module.exports = function (client) {
Company.prototype.client = Company.client = client;
Company.NotFoundError = utils.NotFoundError;
Company.QueuedError = utils.QueuedError;
return Company;
};
......@@ -10,8 +10,6 @@ module.exports = function (client) {
_.extend(this, data);
}
Person.prototype.pending = utils.pending;
Person.find = Promise.method(function (options) {
assert(options && options.email, 'An email must be provided');
return this.client.request(_.extend({
......@@ -21,6 +19,9 @@ module.exports = function (client) {
}, options))
.bind(this)
.then(utils.cast)
.catch(utils.isQueued, function () {
throw new this.QueuedError('Person lookup queued');
})
.catch(utils.isUnknownRecord, function () {
throw new this.NotFoundError('Person not found');
});
......@@ -28,6 +29,7 @@ module.exports = function (client) {
Person.prototype.client = Person.client = client;
Person.NotFoundError = utils.NotFoundError;
Person.QueuedError = utils.QueuedError;
return Person;
};
......@@ -10,8 +10,6 @@ module.exports = function (client) {
_.extend(this, data);
}
PersonCompany.prototype.pending = utils.pending;
PersonCompany.find = Promise.method(function (options) {
assert(options && options.email, 'An email must be provided');
return this.client.request(_.extend({
......@@ -21,6 +19,9 @@ module.exports = function (client) {
}, options))
.bind(this)
.then(utils.cast)
.catch(utils.isQueued, function () {
throw new this.QueuedError('PersonCompany lookup queued');
})
.catch(utils.isUnknownRecord, function () {
throw new this.NotFoundError('PersonCompany not found');
});
......@@ -28,6 +29,7 @@ module.exports = function (client) {
PersonCompany.prototype.client = PersonCompany.client = client;
PersonCompany.NotFoundError = utils.NotFoundError;
PersonCompany.QueuedError = utils.QueuedError;
return PersonCompany;
};
......@@ -6,12 +6,13 @@ exports.cast = function (data) {
return new this(data);
};
exports.pending = function () {
return !this.id;
};
exports.NotFoundError = createError('NotFoundError');
exports.QueuedError = createError('QueuedError');
exports.isUnknownRecord = function (err) {
return err.type === 'unknown_record';
};
exports.isQueued = function (err) {
return err.type === 'queued';
};
\ No newline at end of file
......@@ -80,7 +80,7 @@ describe('Client', function () {
it('sends a get request to the specified endpoint', function () {
mock
.get('/v1/people/email/bvdrucker@gmail.com')
.reply(202);
.reply(200);
return client.request({
api: 'person',
path: '/people/email/bvdrucker@gmail.com'
......@@ -90,7 +90,7 @@ describe('Client', function () {
it('can generate a qs', function () {
mock
.get('/v1/people/email/bvdrucker@gmail.com?webhook_id=123')
.reply(202);
.reply(200);
return client.request({
api: 'person',
path: '/people/email/bvdrucker@gmail.com',
......@@ -119,7 +119,7 @@ describe('Client', function () {
mock
.get('/v1/people/email/bvdrucker@gmail.com')
.matchHeader('Authorization', 'Basic azo=')
.reply(202);
.reply(200);
return client.request({
api: 'person',
path: '/people/email/bvdrucker@gmail.com'
......@@ -130,7 +130,7 @@ describe('Client', function () {
mock
.get('/v1/people/email/bvdrucker@gmail.com')
.matchHeader('User-Agent', 'ClearbitNode/v' + pkg.version)
.reply(202);
.reply(200);
return client.request({
api: 'person',
path: '/people/email/bvdrucker@gmail.com'
......
......@@ -15,17 +15,6 @@ describe('Company', function () {
mock.done();
});
describe('#pending', function () {
it('identifies whether the company has an id', function () {
var company = new Company();
expect(company.pending()).to.be.true;
company.id = 'foo';
expect(company.pending()).to.be.false;
});
});
describe('Company#find', function () {
var company = require('./fixtures/company');
......@@ -42,14 +31,17 @@ describe('Company', function () {
});
});
it('can handle pending requests', function () {
it('can handle queued requests', function () {
mock
.get('/v1/companies/domain/uber.com')
.reply(202);
return Company.find({domain: 'uber.com'})
.then(function (company) {
expect(company.pending()).to.be.true;
.reply(202, {
error: {
type: 'queued'
}
});
return Company.find({domain: 'uber.com'})
.to.be.rejectedWith(Company.QueuedError);
});
it('can handle unknown records', function () {
......
......@@ -15,17 +15,6 @@ describe('Person', function () {
mock.done();
});
describe('#pending', function () {
it('identifies whether the person has an id', function () {
var person = new Person();
expect(person.pending()).to.be.true;
person.id = 'foo';
expect(person.pending()).to.be.false;
});
});
describe('Person#find', function () {
var alex = require('./fixtures/person');
......@@ -56,14 +45,16 @@ describe('Person', function () {
return Person.find({email: 'alex@alexmaccaw.com', company: false});
});
it('can handle pending requests', function () {
it('can handle queued requests', function () {
mock
.get('/v1/people/email/alex@alexmaccaw.com')
.reply(202);
return Person.find({email: 'alex@alexmaccaw.com'})
.then(function (person) {
expect(person.pending()).to.be.true;
.reply(202, {
error: {
type: 'queued'
}
});
return Person.find({email: 'alex@alexmaccaw.com'})
.to.be.rejectedWith(Company.QueuedError);
});
it('can handle unknown records', function () {
......
......@@ -15,17 +15,6 @@ describe('PersonCompany', function () {
mock.done();
});
describe('#pending', function () {
it('identifies whether the person has an id', function () {
var person = new PersonCompany();
expect(person.pending()).to.be.true;
person.id = 'foo';
expect(person.pending()).to.be.false;
});
});
describe('PersonCompany#find', function () {
var alex = require('./fixtures/person');
......@@ -42,14 +31,16 @@ describe('PersonCompany', function () {
});
});
it('can handle pending requests', function () {
it('can handle queued requests', function () {
mock
.get('/v1/combined/email/alex@alexmaccaw.com')
.reply(202);
return PersonCompany.find({email: 'alex@alexmaccaw.com'})
.then(function (person) {
expect(person.pending()).to.be.true;
.reply(202, {
error: {
type: 'queued'
}
});
return PersonCompany.find({email: 'alex@alexmaccaw.com'})
.to.be.rejectedWith(PersonCompany.QueuedError);
});
});
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment