first version
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 2025 SimcuTeam. All rights reserved.
|
||||
* 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。
|
||||
*/
|
||||
|
||||
package simapi.middlewares
|
||||
|
||||
import soulsoft_web_http.*
|
||||
import soulsoft_extensions_logging.*
|
||||
import simapi.communications.*
|
||||
import simapi.exceptions.*
|
||||
import simapi.configurations.*
|
||||
|
||||
/**
|
||||
* 异常处理中间件:全异常捕获,统一输出 HTTP 200 + JSON 响应。
|
||||
* 对应 C# 的 SimApi.Middlewares.SimApiExceptionMiddleware。
|
||||
*/
|
||||
public class SimApiExceptionMiddleware <: IMiddleware {
|
||||
private let _options: SimApiOptions
|
||||
private let _logger: ILogger
|
||||
|
||||
public init(options: SimApiOptions, loggerFactory: ILoggerFactory) {
|
||||
_options = options
|
||||
_logger = loggerFactory.createLogger("SimApi.ExceptionMiddleware")
|
||||
}
|
||||
|
||||
/**
|
||||
* 中间件入口(IMiddleware 风格,对齐 C# UseMiddleware<T> 的 InvokeAsync)。
|
||||
*/
|
||||
public func invoke(context: HttpContext, next: RequestDelegate): Unit {
|
||||
try {
|
||||
// 透传 Query-Id 请求头
|
||||
if (let Some(queryId) <- context.request.headers.get("Query-Id")) {
|
||||
context.response.headers.add("Query-Id", queryId)
|
||||
}
|
||||
next(context)
|
||||
// 若响应未开始且状态码不在跳过列表,则视为业务错误
|
||||
if (!context.response.hasStarted) {
|
||||
let code = Int64(context.response.statusCode)
|
||||
if (!_options.simApiExceptionOptions.skipStatusCodes.contains(code)) {
|
||||
throw SimApiException(code)
|
||||
}
|
||||
}
|
||||
} catch (ex: Exception) {
|
||||
let response = buildResponse(ex, context)
|
||||
if (!context.response.hasStarted) {
|
||||
context.response.statusCode = 200
|
||||
context.response.contentType = "application/json; charset=utf-8"
|
||||
context.response.write(responseJson(response))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func buildResponse(ex: Exception, context: HttpContext): SimApiBaseResponse {
|
||||
if (let simEx: SimApiException <- ex) {
|
||||
let message = if (simEx.message.isEmpty()) {
|
||||
SimApiBaseResponse.getDefaultMessage(simEx.code)
|
||||
} else {
|
||||
simEx.message
|
||||
}
|
||||
var response = SimApiBaseResponse(simEx.code, message)
|
||||
if (context.response.statusCode == 404) {
|
||||
response.message = "接口不存在"
|
||||
}
|
||||
return response
|
||||
}
|
||||
_logger.error(EventId(0), ex, ex.message)
|
||||
return SimApiBaseResponse(500)
|
||||
}
|
||||
|
||||
private func responseJson(response: SimApiBaseResponse): String {
|
||||
response.toJsonString()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user