JS «Непривязанная точка останова» при попытке отладки файлов с использованием swaggerAPIJavascript

Форум по Javascript
Ответить
Anonymous
 JS «Непривязанная точка останова» при попытке отладки файлов с использованием swaggerAPI

Сообщение Anonymous »

Я столкнулся с проблемой при отладке файлов JavaScript и TypeScript в проекте, использующем сервер Express и API Swagger (Swagger).
Проблема возникает при попытке установить точки останова в контроллере. файлы. Эти точки останова не установлены, и я получаю сообщение об ошибке: "Непривязанная точка останова". Однако я могу без проблем отлаживать файлы инициализации, такие как index.ts и expressServer.js.
Шаги для воспроизведения:
  • Добавьте точку останова в index.ts
  • Добавьте точку останова в expressServer .js
  • Добавить точку останова в некоторые файлов контроллера.
  • Запустите отладчик (Сервер остановлен)
  • Отладчик прерывает работу файла index.ts
  • При продолжении (F5) прерывает работу expressServer.js
  • Взгляните на точку останова в некоторых файлы контроллера и убедитесь, что он неактивен с сообщением «Непривязанная точка останова»
  • Запросите сервер через Postman
    < /li>
    Невозможно отправить запрос (бесконечная загрузка), так как сервер не запущен
Примечание: я тестирую его на виртуальной машине с NodeJS. v20.17.0 и TypeScript 5.7.2

Я подозреваю, что проблема связана с конфигурацией Swagger API. Файл конфигурации openapi.yaml, используемый Swagger, по-видимому, распределяет запросы на контроллеры и их конечные точки, делая эти файлы недоступными для отладчика. Если это предположение неверно, я был бы признателен за любые разъяснения или рекомендации по решению этой проблемы.
Спасибо за помощь.
Файлы инициализации сервера:
expressServer.js
// const { Middleware } = require('swagger-express-middleware')
const http = require('http')
const https = require('https')
const fs = require('fs')
const path = require('path')
const swaggerUI = require('swagger-ui-express')
const jsYaml = require('js-yaml')
const express = require('express')
const cors = require('cors')
const cookieParser = require('cookie-parser')
const bodyParser = require('body-parser')
const OpenApiValidator = require('express-openapi-validator')
const logger = require('./logger')
const config = require('./config')

const { getBasePath } = require('./utils/swaggerUtils')
const { updateAPISpecification } = require('./utils/fixes')

const { entrypoint } = require('./utils/entrypoint')

const cleanPath = (path) => path.replace(/\/\//,'/')

class ExpressServer {
constructor(port, openApiYaml) {
this.port = port;
this.app = express();
this.openApiPath = openApiYaml;
try {

this.schema = jsYaml.safeLoad(fs.readFileSync(openApiYaml))

updateAPISpecification(this.schema, openApiYaml)

} catch (e) {
logger.error('failed to start Express Server', e.message)
}

this.setupMiddleware()

}

setupMiddleware() {

const basePath = getBasePath().replace(/\/$/,'')

// this.setupAllowedMedia();
this.app.use(cors())
// this.app.use(bodyParser.json({ limit: '14MB' }))
this.app.use(express.json())
this.app.use(express.text())
this.app.use(express.urlencoded({ extended: false }))
this.app.use(cookieParser())

//Simple test to see that the server is up and responding
this.app.get('/hello', (req, res) => res.send(`Hello World. path: ${this.openApiPath}`))

const openapi=config.OPENAPI || '/openapi'

//Send the openapi document *AS GENERATED BY THE GENERATOR*
this.app.get(cleanPath(`${basePath}${openapi}`), (req, res) => res.sendFile((path.join(__dirname, 'api', 'openapi.yaml'))))

//View the openapi document in a visual interface. Should be able to test from this page
this.app.use(cleanPath(`${basePath}/api-docs`), swaggerUI.serve, swaggerUI.setup(this.schema))

this.app.get('/login-redirect', (req, res) => {
res.status(200)
res.json(req.query)
})

this.app.get('/oauth2-redirect.html', (req, res) => {
res.status(200)
res.json(req.query)
})

this.app.get(`${openapi}`, function(req, res) {
res.redirect(cleanPath(`${basePath}/${openapi}`))
})

this.app.get('/api-docs', function(req, res) {
res.redirect(cleanPath(`${basePath}/api-docs`))
})

this.app.use(cleanPath(`${basePath}/entrypoint`), entrypoint)

this.app.get('/', function(req, res) {
res.redirect(cleanPath(`${basePath}/entrypoint`))
})

this.app.get(cleanPath(`${basePath}/`), function(req, res) {
res.redirect(cleanPath(`${basePath}/entrypoint`))
})

const apiTimeout = 5 * 1000
if(false) this.app.use((req, res, next) => {
// Set the timeout for all responses
res.setTimeout(apiTimeout, () => {
let err = new Error('Service Unavailable')
err.status = 503
next(err)
})
})

}

launch() {

try {

this.app.use( OpenApiValidator.middleware({
apiSpec: this.openApiPath,
operationHandlers: path.join(__dirname, 'built'),
validateRequests: true, // (default)
validateResponses: true, // false by default
unknownFormats: ['base64']
}))

// this.app.use(validator)

logger.info(`validator installed`)

this.app.use((err, req, res, next) => {
// format errors
res.status(err.status || 500).json({
message: err.message || err,
errors: err.errors || '',
})
})

let server;

const fullchainPath = '/certificates/fullchain.pem';
const privkeyPath = '/certificates/privkey.pem';

if (fs.existsSync(fullchainPath) && fs.existsSync(privkeyPath)) {
logger.info('Running with SSL');
const sslCert = {
cert: fs.readFileSync('/certificates/fullchain.pem'),
key: fs.readFileSync('/certificates/privkey.pem')
};
server = https.createServer(sslCert, this.app)
} else {
logger.info('Running without SSL');
server = http.createServer(this.app)
}

server.listen(this.port)

logger.info(`Listening on port ${this.port}`)

} catch(e) {
logger.error(`launch error: ` + e)
}

}

async close() {
if (this.server !== undefined) {
await this.server.close();
logger.info(`Server on port ${this.port} shut down`)
}
}
}

module.exports = ExpressServer;

index.ts
import config from './config';
import logger from './logger';
import ExpressServer from './expressServer';

import Service from './services/Service';
import NotificationHandler from './services/NotificationHandler';

import plugins from './plugins/plugins';

Service.setDB(plugins.db);
Service.setNotifier(NotificationHandler);

NotificationHandler.setDB(plugins.db);
NotificationHandler.setQueue(plugins.queue);

class ServerLauncher {
private expressServer: ExpressServer | undefined;

public async launchServer(): Promise {
try {
this.expressServer = new ExpressServer(config.URL_PORT, config.OPENAPI_YAML);
await this.expressServer.launch();
logger.info('Express server running');
} catch (error) {
logger.error(error);
await this.close();
}
}

private async close(): Promise {
if (this.expressServer) {
await this.expressServer.close();
}
}
}

const serverLauncher = new ServerLauncher();

serverLauncher.launchServer().catch((error) => logger.error(error));

Я использую следующую конфигурацию:
launch.json
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"skipFiles": ["/**"],
"program": "${workspaceFolder}/built/index.js",
"preLaunchTask": "tsc: build - tsconfig.json",
"outFiles": ["${workspaceFolder}/built/**/*.js"],
"port": 9229
}
]
}

tsconfig.json
{
"compilerOptions": {
"target": "ES6", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
"module": "commonjs", /* Specify what module code is generated. */
"rootDir": "./", /* Specify the root folder within your source files. */
"allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
"outDir": "./built", /* Specify an output folder for all emitted files. */
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
"strict": true, /* Enable all strict type-checking options. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
},
"include": ["/**/*.ts"],
"exclude": ["node_modules", "**/*.spec.ts"]
}


Подробнее здесь: https://stackoverflow.com/questions/793 ... swaggerapi
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Javascript»