在 Ubuntu 上,Swagger 的错误处理包含两部分:一是在 OpenAPI/Swagger 文档里声明错误响应模型与状态码;二是在后端代码与中间件中按声明返回结构化错误;三是用 Swagger UI 验证并在出现问题时按 Linux/Ubuntu 的通用路径排查。
openapi: 3.0.3
info:
title: Sample API
version: 1.0.0
paths:
/items/{itemId}:
get:
parameters:
- in: path
name: itemId
required: true
schema:
type: string
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Item'
'400':
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'404':
description: Not Found
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
description: Internal Server Error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
components:
schemas:
Item:
type: object
properties:
id:
type: string
name:
type: string
ErrorResponse:
type: object
properties:
code:
type: integer
format: int32
message:
type: string
details:
type: array
items:
type: object
properties:
field:
type: string
message:
type: string
{
"swagger": "2.0",
"info": { "title": "Sample API", "version": "1.0.0" },
"paths": {
"/items/{itemId}": {
"get": {
"parameters": [
{
"in": "path",
"name": "itemId",
"type": "string",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": { "$ref": "#/definitions/Item" }
},
"400": {
"description": "Bad Request",
"schema": { "$ref": "#/definitions/ErrorResponse" }
},
"404": {
"description": "Not Found",
"schema": { "$ref": "#/definitions/ErrorResponse" }
},
"500": {
"description": "Internal Server Error",
"schema": { "$ref": "#/definitions/ErrorResponse" }
}
}
}
}
},
"definitions": {
"Item": {
"type": "object",
"properties": {
"id": { "type": "string" },
"name": { "type": "string" }
}
},
"ErrorResponse": {
"type": "object",
"properties": {
"code": { "type": "integer", "format": "int32" },
"message": { "type": "string" },
"details": {
"type": "array",
"items": {
"type": "object",
"properties": {
"field": { "type": "string" },
"message": { "type": "string" }
}
}
}
}
}
}
}
要点:错误模型建议包含业务错误码 code、人类可读消息 message、可选的字段级错误 details,并在每个接口显式列出可能返回的4xx/5xx状态码。
const express = require('express');
const swaggerUi = require('swagger-ui-express');
const YAML = require('yamljs');
const app = express();
const swaggerDocument = YAML.load('./swagger.yaml');
// 统一错误处理中间件(放在所有路由之后)
app.use((err, req, res, next) => {
console.error(err.stack);
const status = err.status || 500;
const payload = {
code: status,
message: err.message || 'Internal Server Error',
details: err.details || null
};
res.status(status).json(payload);
});
// 业务示例
app.get('/items/:itemId', (req, res, next) => {
const { itemId } = req.params;
if (!itemId) {
const err = new Error('itemId is required');
err.status = 400;
err.details = [{ field: 'itemId', message: 'must be provided' }];
return next(err);
}
// 模拟未找到
if (itemId === 'not-exist') {
const err = new Error('Item not found');
err.status = 404;
return next(err);
}
res.json({ id: itemId, name: 'Sample' });
});
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument));
app.listen(3000, () => console.log('Server on http://localhost:3000'));
sudo ufw allow 3000。