Skip to content

Commit efe7710

Browse files
authored
Throw qualified errors (#118)
* Throw qualified errors * Tweaks
1 parent 6639bdb commit efe7710

File tree

9 files changed

+44
-68
lines changed

9 files changed

+44
-68
lines changed

README.md

+6-7
Original file line numberDiff line numberDiff line change
@@ -258,13 +258,6 @@ Call the instance for extracting content based on rules bundle provided at the c
258258

259259
#### options
260260

261-
##### html
262-
263-
*Required*<br>
264-
Type: `String`
265-
266-
The HTML markup for extracting the content.
267-
268261
#### url
269262

270263
*Required*<br>
@@ -276,6 +269,12 @@ It is used for resolve relative links that can be present in the HTML markup.
276269

277270
it can be used as fallback field for different rules as well.
278271

272+
##### html
273+
274+
Type: `String`
275+
276+
The HTML markup for extracting the content.
277+
279278
#### rules
280279

281280
Type: `Array`

packages/metascraper-clearbit-logo/index.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ const DEFAULTS = {
1212
const ENDPOINT = 'https://logo.clearbit.com'
1313

1414
module.exports = opts => {
15-
opts = Object.assign({}, DEFAULTS, opts)
15+
opts = { ...DEFAULTS, ...opts }
16+
1617
const { size, format, greyscale } = opts
1718

1819
const clearbitLogo = async ({ url }) => {

packages/metascraper-clearbit-logo/test/index.js

+2-13
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,12 @@
22

33
const should = require('should')
44

5-
const metascraper = require('metascraper')([
6-
require('metascraper-author')(),
7-
require('metascraper-date')(),
8-
require('metascraper-description')(),
9-
require('metascraper-image')(),
10-
require('metascraper-logo')(),
11-
require('metascraper-clearbit-logo')(),
12-
require('metascraper-publisher')(),
13-
require('metascraper-title')(),
14-
require('metascraper-url')()
15-
])
5+
const metascraper = require('metascraper')([require('..')()])
166

177
describe('metascraper-clearbit-logo', () => {
188
it('returns when is possible resolve logo', async () => {
199
const url = 'https://facebook.com'
20-
const html = '<div></div>'
21-
const meta = await metascraper({ html, url })
10+
const meta = await metascraper({ url })
2211
should(meta.logo.indexOf('clearbit') !== -1).be.true()
2312
})
2413

packages/metascraper-helpers/index.js

+6-4
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,9 @@ const REGEX_LOCATION = /^[A-Z\s]+\s+[-—–]\s+/
4242

4343
const removeLocation = value => replace(value, REGEX_LOCATION, '')
4444

45-
const urlTest = (url, { relative = true }) =>
45+
const isUrl = (url, { relative = false } = {}) =>
4646
relative ? isRelativeUrl(url) || urlRegex.test(url) : urlRegex.test(url)
4747

48-
const isUrl = (url, opts = {}) => !isEmpty(url) && urlTest(url, opts)
49-
5048
const absoluteUrl = (baseUrl, relativePath = '') =>
5149
resolveUrl(baseUrl, relativePath)
5250

@@ -118,7 +116,11 @@ const publisher = value => isString(value) && condenseWhitespace(value)
118116

119117
const author = value => isAuthor(value) && getAuthor(value)
120118

121-
const url = (value, { url }) => isUrl(value) && normalizeUrl(url, value)
119+
const url = (value, { url }) => {
120+
if (isEmpty(value)) return false
121+
const absoluteUrl = normalizeUrl(url, value)
122+
return isUrl(absoluteUrl) && absoluteUrl
123+
}
122124

123125
const date = value => {
124126
if (!value) return false
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,4 @@
11
exports['create an absolute favicon url if the logo is not present 1'] = {
2-
"lang": "en",
3-
"author": "Mat Follas",
4-
"title": "Vegetable Perfection: 100 delicious recipes for roots, bulbs, shoots and stems",
5-
"publisher": "Amazon",
6-
"image": "https://images-eu.ssl-images-amazon.com/images/I/61Q2c36lYeL._SX218_BO1,204,203,200_QL40_.jpg",
7-
"description": "Buy Vegetable Perfection: 100 delicious recipes for roots, bulbs, shoots and stems by Mat Follas (ISBN: 9781849757096) from Amazon’s Book Store. Everyday low prices and free delivery on eligible orders.",
8-
"logo": "https://www.amazon.co.uk/favicon.ico",
9-
"url": "https://www.amazon.co.uk/Vegetable-Perfection-delicious-recipes-shoots/dp/1849757097"
2+
"logo": "https://www.amazon.co.uk/favicon.ico"
103
}
114

packages/metascraper-logo-favicon/test/index.js

+1-12
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,7 @@ const { resolve } = require('path')
66
const { omit } = require('lodash')
77
const fs = require('fs')
88

9-
const metascraper = require('metascraper')([
10-
require('metascraper-amazon')(),
11-
require('metascraper-author')(),
12-
require('metascraper-date')(),
13-
require('metascraper-description')(),
14-
require('metascraper-image')(),
15-
require('metascraper-logo')(),
16-
require('..')(),
17-
require('metascraper-publisher')(),
18-
require('metascraper-title')(),
19-
require('metascraper-url')()
20-
])
9+
const metascraper = require('metascraper')([require('..')()])
2110

2211
const readFile = promisify(fs.readFile)
2312

packages/metascraper/package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@
5656
"cheerio-advanced-selectors": "~2.0.1",
5757
"lodash": "~4.17.10",
5858
"p-reduce": "~1.0.0",
59-
"sanitize-html": "~1.18.2"
59+
"sanitize-html": "~1.18.2",
60+
"whoops": "~4.0.1"
6061
},
6162
"devDependencies": {
6263
"clear-module": "latest",

packages/metascraper/src/index.js

+9-4
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,25 @@
11
'use strict'
22

33
const { isUrl } = require('@metascraper/helpers')
4-
const { isEmpty } = require('lodash')
4+
const whoops = require('whoops')
55

66
const mergeRules = require('./merge-rules')
77
const loadRules = require('./load-rules')
88
const loadHTML = require('./load-html')
99
const getData = require('./get-data')
1010

11+
const MetascraperError = whoops('MetascraperError')
12+
1113
module.exports = rules => {
1214
const loadedRules = loadRules(rules)
1315
return async ({ url, html, rules: inlineRules } = {}) => {
14-
if (!isUrl(url)) throw new TypeError('You need to provide a valid url.')
15-
if (isEmpty(html)) {
16-
throw new TypeError('You need to provide a valid HTML markup.')
16+
if (!isUrl(url)) {
17+
throw new MetascraperError({
18+
message: 'Need to provide a valid URL.',
19+
code: 'INVALID_URL'
20+
})
1721
}
22+
1823
return getData({
1924
url,
2025
htmlDom: loadHTML(html),

packages/metascraper/test/unit/interface.js

+15-18
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,29 @@
22

33
const should = require('should')
44

5-
const metascraper = require('../..')([
6-
require('metascraper-author')(),
7-
require('metascraper-date')(),
8-
require('metascraper-description')(),
9-
require('metascraper-video')(),
10-
require('metascraper-image')(),
11-
require('metascraper-lang')(),
12-
require('metascraper-logo')(),
13-
require('metascraper-publisher')(),
14-
require('metascraper-title')(),
15-
require('metascraper-url')()
16-
])
5+
const metascraper = require('../..')([])
176

187
it('url is required', async () => {
198
try {
209
await metascraper()
2110
} catch (err) {
22-
should(err).instanceof(TypeError)
11+
should(err.name).be.equal('MetascraperError')
12+
should(err.code).be.equal('INVALID_URL')
13+
should(err.message).be.equal('INVALID_URL, Need to provide a valid URL.')
14+
}
15+
try {
16+
await metascraper({ url: '' })
17+
} catch (err) {
18+
should(err.name).be.equal('MetascraperError')
19+
should(err.code).be.equal('INVALID_URL')
20+
should(err.message).be.equal('INVALID_URL, Need to provide a valid URL.')
2321
}
24-
})
25-
26-
it('html is required', async () => {
2722
try {
28-
await metascraper({ url: 'https://foo.com' })
23+
await metascraper({ url: '/foo' })
2924
} catch (err) {
30-
should(err).instanceof(TypeError)
25+
should(err.name).be.equal('MetascraperError')
26+
should(err.code).be.equal('INVALID_URL')
27+
should(err.message).be.equal('INVALID_URL, Need to provide a valid URL.')
3128
}
3229
})
3330

0 commit comments

Comments
 (0)