Quellcode durchsuchen

storage-node-v2: Change web api error handling.

Shamil Gadelshin vor 3 Jahren
Ursprung
Commit
929da02e82

+ 23 - 0
storage-node-v2/src/api-spec/openapi.yaml

@@ -65,6 +65,13 @@ paths:
                     type: boolean
         401:
           description: Unauthorized
+        410:
+          description: Upload request problem
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ErrorResponse'
+
   /authToken:
     post:
       description: Get auth token from a server.
@@ -87,6 +94,13 @@ paths:
                 properties:
                   token:
                     type: string
+        400:
+          description: Bad request
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ErrorResponse'
+
 components:
   securitySchemes:
     UploadAuth:
@@ -102,3 +116,12 @@ components:
         dataObjectId:
           type: integer
           format: int64
+    ErrorResponse:
+      type: object
+      required:
+        - message
+      properties:
+        type:
+          type: string
+        message:
+          type: string

+ 1 - 1
storage-node-v2/src/services/logger.ts

@@ -51,7 +51,7 @@ const Logger = createDefaultLogger()
 export default Logger
 
 // Creates Express-Winston logger handler.
-export function getHttpLogger(): Handler {
+export function httpLogger(): Handler {
   const opts: expressWinston.LoggerOptions = {
     transports: [new winston.transports.Console()],
     format: winston.format.combine(

+ 8 - 17
storage-node-v2/src/services/runtime/api.ts

@@ -117,31 +117,20 @@ function sendExtrinsic(
   })
 }
 
+// TODO: Refactor sendTx* methods.
 export async function sendAndFollowTx(
   api: ApiPromise,
   account: KeyringPair,
   tx: SubmittableExtrinsic<'promise'>
 ): Promise<boolean> {
-  try {
-    const nonce = await getNonce(api, account)
+  const nonce = await getNonce(api, account)
 
-    await sendExtrinsic(api, account, tx, nonce)
-    logger.debug(`Extrinsic successful!`)
-    return true
-  } catch (e) {
-    if (e instanceof ExtrinsicFailedError) {
-      throw new ExtrinsicFailedError(
-        `Extrinsic failed! Message: ${e.message}`,
-        {
-          exit: ExitCodes.ApiError,
-        }
-      )
-    } else {
-      throw e
-    }
-  }
+  await sendExtrinsic(api, account, tx, nonce)
+  logger.debug(`Extrinsic successful!`)
+  return true
 }
 
+// TODO: Refactor sendTx* methods.
 export async function sendAndFollowNamedTx(
   api: ApiPromise,
   account: KeyringPair,
@@ -154,6 +143,7 @@ export async function sendAndFollowNamedTx(
   return await sendAndFollowTx(api, account, tx)
 }
 
+// TODO: Refactor sendTx* methods.
 export async function sendAndFollowSudoNamedTx(
   api: ApiPromise,
   account: KeyringPair,
@@ -166,6 +156,7 @@ export async function sendAndFollowSudoNamedTx(
   return await sendAndFollowTx(api, account, tx)
 }
 
+// TODO: Move to accounts.ts
 export function getAlicePair(): KeyringPair {
   const keyring = new Keyring({ type: 'sr25519' })
   return keyring.addFromUri('//Alice')

+ 28 - 7
storage-node-v2/src/services/webApi/app.ts

@@ -3,17 +3,20 @@ import path from 'path'
 import cors from 'cors'
 import { Express, NextFunction } from 'express-serve-static-core'
 import * as OpenApiValidator from 'express-openapi-validator'
-import { OpenAPIV3 } from 'express-openapi-validator/dist/framework/types'
+import {
+  HttpError,
+  OpenAPIV3,
+} from 'express-openapi-validator/dist/framework/types'
 import { KeyringPair } from '@polkadot/keyring/types'
 import { ApiPromise } from '@polkadot/api'
 import { TokenRequest, verifyTokenSignature } from '../helpers/auth'
 import { createStorageBucket } from '../runtime/extrinsics'
-import { parseBagId } from '../../services/helpers/bagIdParser'
-import { getHttpLogger } from '../../services/logger'
+import { httpLogger } from '../../services/logger'
 
 // TODO: custom errors (including validation errors)
 // TODO: custom authorization errors
 
+// Creates web API application.
 export async function createApp(
   api: ApiPromise,
   account: KeyringPair,
@@ -26,7 +29,7 @@ export async function createApp(
 
   app.use(cors())
   app.use(express.json())
-  app.use(getHttpLogger())
+  app.use(httpLogger())
 
   // TODO: check path
   app.use('/files', express.static(uploadsDir))
@@ -45,6 +48,7 @@ export async function createApp(
       res.locals.api = api
       next()
     },
+    // Setup OpenAPiValidator
     OpenApiValidator.middleware({
       apiSpec: spec,
       validateApiSpec: true,
@@ -63,15 +67,35 @@ export async function createApp(
     })
   )
 
+  // Request validation error handler.
+  /* eslint-disable @typescript-eslint/no-unused-vars */ // Required signature.
+  app.use(
+    (
+      err: HttpError,
+      req: express.Request,
+      res: express.Response,
+      next: express.NextFunction
+    ) => {
+      res.status(err.status).json({
+        type: 'request_validation',
+        message: err.message,
+        errors: err.errors,
+      })
+      next(err)
+    }
+  )
+
   return app
 }
 
+// Defines a signature for a upload validation function.
 type ValidateUploadFunction = (
   req: express.Request,
   scopes: string[],
   schema: OpenAPIV3.SecuritySchemeObject
 ) => boolean | Promise<boolean>
 
+// Creates upload validation function.
 function validateUpload(
   api: ApiPromise,
   account: KeyringPair
@@ -85,9 +109,6 @@ function validateUpload(
   ) => {
     const tokenSignature = req.headers['x-api-key'] as string
 
-    // Validate bagId.
-    parseBagId(api, req.body.bagId)
-
     // TODO: token construction
     const sourceTokenRequest: TokenRequest = {
       dataObjectId: parseInt(req.body.dataObjectId),

+ 3 - 2
storage-node-v2/src/services/webApi/controllers/publicApi.ts

@@ -44,8 +44,9 @@ export async function upload(
       file: 'received',
     })
   } catch (err) {
-    res.status(500).json({
-      errorMsg: err.toString(),
+    res.status(410).json({
+      type: 'Upload error',
+      message: err.toString(),
     })
   }
 }