Skip to content

Commit

Permalink
Merge pull request #3 from zazuko/remote-improvements
Browse files Browse the repository at this point in the history
fix: handle fetch fails
  • Loading branch information
tpluscode authored Dec 1, 2023
2 parents d42f222 + d850bf9 commit 5dfbbc0
Show file tree
Hide file tree
Showing 9 changed files with 73 additions and 21 deletions.
5 changes: 5 additions & 0 deletions .changeset/selfish-pens-mix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"rdf-transform-graph-imports": patch
---

Failures to fetch remote import would break the stream
4 changes: 2 additions & 2 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ function transform(env: Environment, { basePath }: Options = {}) {
})

for (const importTarget of imports) {
const importStream = fetchImport(env, importTarget)
.pipe(transform(env, { basePath: importTarget }))
const fetchStream = await fetchImport(env, importTarget)
const importStream = fetchStream.pipe(transform(env, { basePath: importTarget }))

for await (const importedQuad of importStream) {
this.push(importedQuad)
Expand Down
22 changes: 7 additions & 15 deletions lib/fetchImport.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,15 @@
import { Readable, PassThrough } from 'readable-stream'
import { Readable } from 'readable-stream'
import Environment from './env.js'

export default function (env: Environment, importTarget: string | URL) {
export default async function (env: Environment, importTarget: string | URL) {
if (typeof importTarget === 'string') {
return env.fromFile(importTarget)
}

const remoteStream = new PassThrough({ objectMode: true })

env.fetch(importTarget.toString())
.then(response => {
return response.quadStream() as unknown as Promise<Readable>
})
.then(quadStream => {
quadStream.pipe(remoteStream)
})
.catch(error => {
remoteStream.emit('error', error)
})
const response = await env.fetch(importTarget.toString())
if (!response.ok) {
throw new Error(`Failed to fetch: ${response.statusText}`)
}

return remoteStream
return response.quadStream() as unknown as Promise<Readable>
}
27 changes: 25 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
"@tpluscode/eslint-config": "^0.4.4",
"@types/absolute-url": "^2.0.0",
"@types/chai": "^4.3.9",
"@types/chai-as-promised": "^7.1.8",
"@types/express": "^4.17.20",
"@types/is-uri": "^1.0.2",
"@types/mocha": "^10.0.3",
Expand All @@ -60,6 +61,7 @@
"absolute-url": "^2.0.0",
"c8": "^8.0.1",
"chai": "^4.3.10",
"chai-as-promised": "^7.1.1",
"eslint-import-resolver-typescript": "^3.6.1",
"express": "^4.18.2",
"husky": "^8.0.3",
Expand All @@ -77,6 +79,9 @@
},
"mocha": {
"extension": "ts",
"loader": "ts-node/esm"
"loader": "ts-node/esm",
"require": [
"test/mocha-setup.cjs"
]
}
}
10 changes: 10 additions & 0 deletions test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,16 @@ describe('rdf-merge-stream', () => {
// then
expect(await turtle(merged)).toMatchSnapshot()
})

it('fails when remote resource is not found', async () => {
// given
const response = await rdf.fetch('http://localhost:6666/invalid-import')
const root = await response.quadStream() as unknown as Readable

// then
await expect(rdf.dataset().import(root.pipe(transform(rdf))))
.to.be.eventually.rejectedWith('Failed to fetch: Not Found')
})
})

async function turtle(merged: Dataset) {
Expand Down
4 changes: 4 additions & 0 deletions test/mocha-setup.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
const chai = require('chai')
const chaiAsPromised = require('chai-as-promised')

chai.use(chaiAsPromised);
8 changes: 7 additions & 1 deletion test/server/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as url from 'url'
import * as path from 'path'
import * as fs from 'fs'
import express from 'express'
import * as absoluteUrl from 'absolute-url'
import rdfHandler from '@rdfjs/express-handler'
Expand All @@ -14,7 +15,12 @@ export function start() {
.get('/*', (req, res) => {
res.setHeader('Content-Type', 'text/turtle')

const quads = env.fromFile(path.join(__dirname, `${req.path}.ttl`), {
const ttlPath = path.join(__dirname, `${req.path}.ttl`)
if (!fs.existsSync(ttlPath)) {
return res.sendStatus(404)
}

const quads = env.fromFile(ttlPath, {
baseUri: req.absoluteUrl(),
})

Expand Down
7 changes: 7 additions & 0 deletions test/server/resources/invalid-import.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
PREFIX code: <https://code.described.at/>
PREFIX schema: <http://schema.org/>
PREFIX sh: <http://www.w3.org/ns/shacl#>

[
code:imports <foobar> ;
] .

0 comments on commit 5dfbbc0

Please sign in to comment.