Parcourir la source

Added error handler + example with listScenes

rigwild il y a 5 ans
Parent
commit
7c8e2fb280
5 fichiers modifiés avec 65 ajouts et 9 suppressions
  1. 47 0
      api/functions.js
  2. 5 0
      api/index.js
  3. 5 8
      api/routes/listScenes.js
  4. 1 1
      package.json
  5. 7 0
      yarn.lock

+ 47 - 0
api/functions.js

@@ -0,0 +1,47 @@
+'use strict'
+
+import _fs, { promises as fs } from 'fs'
+import boom from 'boom'
+import { apiConfig } from '../config'
+
+/**
+ * Call the error handler if a middleware function throw an error
+ *
+ * @param {Function} fn original middleware function of the route
+ * @returns {Function} the same middleware function of the route but error handled
+ */
+export const asyncMiddleware = fn => (req, res, next) => {
+  Promise.resolve(fn(req, res, next)).catch(err => {
+    // Check whether the error is a boom error
+    if (!err.isBoom) {
+      // The error was not recognized, send a 500 HTTP error
+      return next(boom.internal(err))
+    }
+    // It is a boom error, give it to express to handle it
+    next(err)
+  })
+}
+
+// Middleware to handle middleware errors
+export const errorHandler = (err, req, res, next) => {
+  const { output: { payload } } = err
+  console.error(`Error ${payload.statusCode} - ${payload.error}\n${payload.message}\n`)
+  return res.status(payload.statusCode).json(payload)
+}
+
+/**
+ * Get a list of all available scenes
+ *
+ * @returns {string[]} the available scenes
+ */
+export const getAvailableScenes = async () => {
+  try {
+    // Check if the images directory exists
+    await fs.access(apiConfig.imagesPath, _fs.constants.R_OK)
+  }
+  catch (err) {
+    // The images directory does not exist or is not accessible
+    throw boom.badRequest(`Can't access the "${apiConfig.imagesPath}" directory. Check it exists and you have read permission on it.`)
+  }
+  return fs.readdir(apiConfig.imagesPath)
+}

+ 5 - 0
api/index.js

@@ -3,6 +3,7 @@
 import express from 'express'
 import routes from './routes'
 
+import { errorHandler } from './functions'
 import { apiConfig } from '../config'
 
 const app = express()
@@ -11,4 +12,8 @@ app.listen(apiConfig.port, () => {
   console.log('The server was started on http://localhost:' + apiConfig.port)
 })
 
+// Load all the routes in the server
 app.use(apiConfig.routePrefix, routes)
+
+// Error handler (Middleware called when throwing in another middleware)
+app.use(errorHandler)

+ 5 - 8
api/routes/listScenes.js

@@ -1,17 +1,14 @@
 'use strict'
 
 import express from 'express'
-import { promises } from 'fs'
-
-import { apiConfig } from '../../config'
-
-const fs = promises
+import { asyncMiddleware, getAvailableScenes } from '../functions'
 
 const router = express.Router()
 
-router.get('/', async (req, res) => {
-  const dirContent = await fs.readdir(apiConfig.imagesPath)
+router.get('/', asyncMiddleware(async (req, res) => {
+  const dirContent = await getAvailableScenes()
+  console.log('triggered')
   res.json(dirContent)
-})
+}))
 
 export default router

+ 1 - 1
package.json

@@ -6,12 +6,12 @@
     "api:start": "node -r esm api/index.js",
     "api:dev": "nodemon --exec npm run api:start",
     "api:lint": "eslint api/ --fix",
-
     "app:dev": "vue-cli-service serve",
     "app:build": "vue-cli-service build",
     "app:lint": "vue-cli-service lint"
   },
   "dependencies": {
+    "boom": "^7.3.0",
     "core-js": "^2.6.5",
     "esm": "^3.2.22",
     "express": "^4.16.4",

+ 7 - 0
yarn.lock

@@ -1567,6 +1567,13 @@ boolbase@^1.0.0, boolbase@~1.0.0:
   resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
   integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24=
 
+boom@^7.3.0:
+  version "7.3.0"
+  resolved "https://registry.yarnpkg.com/boom/-/boom-7.3.0.tgz#733a6d956d33b0b1999da3fe6c12996950d017b9"
+  integrity sha512-Swpoyi2t5+GhOEGw8rEsKvTxFLIDiiKoUc2gsoV6Lyr43LHBIzch3k2MvYUs8RTROrIkVJ3Al0TkaOGjnb+B6A==
+  dependencies:
+    hoek "6.x.x"
+
 boxen@^1.2.1:
   version "1.3.0"
   resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b"