Files
simapi-cj/src/middlewares/SimApiExceptionMiddleware.cj
T

76 lines
2.7 KiB
Plaintext
Raw Normal View History

2026-08-16 12:46:15 +08:00
/*
* Copyright (c) 2025 SimcuTeam. All rights reserved.
* 移植自 C# 项目 SimApiE:\simcu\simapi-net),遵循 MIT 许可证。
*/
package simapi.middlewares
import soulsoft_web_http.*
import soulsoft_extensions_logging.*
import simapi_serialization.*
2026-08-16 12:46:15 +08:00
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 = "接口不存在"
2026-08-16 12:46:15 +08:00
}
return response
}
_logger.error(EventId(0), ex, ex.message)
return SimApiBaseResponse(500)
}
private func responseJson(response: SimApiBaseResponse): String {
JsonSerializer.Serialize(response)
2026-08-16 12:46:15 +08:00
}
}