UPDATE: Added the full server code. Notice that the route for static content is working fine, only the one relative to Dat fails. Also, I'm running node 10.8.0
with no transpiler or anything, server is ran with micro -l tcp://0.0.0.0:$PORT
I'm trying to run dat-node
with Zeit micro
. I have this micro service
const { send } = require('micro')
const Dat = require('dat-node')
const handler = require('serve-handler')
const { router, get, post } = require('microrouter')
const static = async (request, response) => {
await handler(request, response, {
// static app folder
public: 'static',
// javascript header for es modules
headers: {
source: '**/*.mjs',
headers: [{
key: 'Content-Type',
value: 'text/javascript'
}]
},
// no directory listing
directoryListing: false
})
}
const createGame = (request, response) => {
Dat('./game', (err, dat) => {
if (err) throw err
let progress = dat.importFiles({watch: true})
progress.on('put', function (src, dest) {
console.log('Importing ', src.name, ' into archive')
})
dat.joinNetwork()
send(response, 200, { key: dat.key.toString('hex') })
})
}
const joinGame = (request, response) => {
}
module.exports = router(
post('/game', createGame),
post('/game/:game', joinGame),
get('/*', static)
)
I just want to create a dat archive and return the public key, but when I call send
I get this error
(node:2054) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:469:11)
at send (/home/ubuntu/workspace/node_modules/micro/lib/index.js:72:8)
at Dat (/home/ubuntu/workspace/index.js:35:5)
at /home/ubuntu/workspace/node_modules/dat-node/index.js:112:9
at apply (/home/ubuntu/workspace/node_modules/thunky/index.js:44:12)
at process._tickCallback (internal/process/next_tick.js:63:19)(node:2054) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)(node:2054) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
So, I'm not sure where the header is being sent, maybe I'm just handling Dat callback in a wrong way? not sure how to implement this service.
The issue appears to be the usage of micro
, not any issue with dat-node
. When you are doing async work in micro, you need to use the async/await
tools of Javascript (promises).
Here is the fixed code:
const createGame = async (request, response) => {
var key = await new Promise((resolve) => {
Dat('./game', (err, dat) => {
if (err) throw err
let progress = dat.importFiles({watch: true})
progress.on('put', function (src, dest) {
console.log('Importing ', src.name, ' into archive')
})
dat.joinNetwork()
resolve(dat.key.toString('hex'))
})
})
console.log('sending')
send(response, 200, { key })
}