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

77 lines
2.7 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* 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.*
import simapi.communications.*
import simapi.exceptions.*
import simapi.configurations.*
import simapi.helpers.*
/**
* 异常处理中间件:全异常捕获,统一输出 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"
SimApiResponseWriter.write(context, 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 {
JsonSerializer.Serialize(response)
}
}