[feat](server): add 502 Bad Gateway support and improve error page handling

- Introduced handling for `502 Bad Gateway` errors with a dedicated HTML template.
- Updated `writeErrorPage` logic to include 502 and other new status mappings for custom templates.
- Improved error page rendering by mapping 4xx/5xx status codes to appropriate templates.
This commit is contained in:
dalbodeule
2025-12-03 01:38:11 +09:00
parent c6b3632784
commit d9ac388761
2 changed files with 59 additions and 5 deletions

View File

@@ -277,8 +277,8 @@ var hopGateOwnedHeaders = map[string]struct{}{
"Referrer-Policy": {},
}
// writeErrorPage 는 주요 HTTP 에러 코드(400/404/500/525)에 대해 정적 HTML 에러 페이지를 렌더링합니다. (ko)
// writeErrorPage renders static HTML error pages for key HTTP error codes (400/404/500/525). (en)
// writeErrorPage 는 주요 HTTP 에러 코드(400/404/500/502/504/525)에 대해 정적 HTML 에러 페이지를 렌더링합니다. (ko)
// writeErrorPage renders static HTML error pages for key HTTP error codes (400/404/500/502/504/525). (en)
//
// 템플릿 로딩 우선순위: (ko)
// 1. HOP_ERROR_PAGES_DIR/<status>.html (또는 ./errors/<status>.html) (ko)
@@ -294,9 +294,31 @@ func writeErrorPage(w http.ResponseWriter, r *http.Request, status int) {
setSecurityAndIdentityHeaders(w, r)
}
// Delegates actual HTML rendering to internal/errorpages. (en)
// 실제 HTML 렌더링은 internal/errorpages 패키지에 위임합니다. (ko)
errorpages.Render(w, r, status)
// 4xx / 5xx 대역에 대한 템플릿 매핑 규칙: (ko)
// - 400 series: 400.html 로 렌더링 (단, 404 는 404.html 사용) (ko)
// - 500 series: 500.html 로 렌더링 (단, 502/504/525 는 개별 템플릿 사용) (ko)
//
// Mapping rules for 4xx / 5xx ranges: (en)
// - 400 series: render using 400.html (except 404 uses 404.html). (en)
// - 500 series: render using 500.html (except 502/504/525 which have dedicated templates). (en)
mapped := status
switch {
case status >= 400 && status < 500:
if status != http.StatusBadRequest && status != http.StatusNotFound {
mapped = http.StatusBadRequest
}
case status >= 500 && status < 600:
if status != http.StatusInternalServerError &&
status != http.StatusBadGateway &&
status != errorpages.StatusGatewayTimeout &&
status != errorpages.StatusTLSHandshakeFailed {
mapped = http.StatusInternalServerError
}
}
// Delegates actual HTML rendering to internal/errorpages with mapped status. (en)
// 실제 HTML 렌더링은 매핑된 상태 코드로 internal/errorpages 패키지에 위임합니다. (ko)
errorpages.Render(w, r, mapped)
}
// setSecurityAndIdentityHeaders 는 HopGate 에서 공통으로 추가하는 보안/식별 헤더를 설정합니다. (ko)

View File

@@ -0,0 +1,32 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>502 Bad Gateway - HopGate</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/__hopgate_assets__/errors.css">
</head>
<body class="min-h-screen bg-slate-950 text-slate-50 flex items-center justify-center px-4">
<div class="w-full max-w-xl text-center">
<div class="items-center justify-center gap-3 mb-8 flex flex-col">
<img src="/__hopgate_assets__/hop-gate.png" alt="HopGate" class="h-8 w-[240px] opacity-90" />
<h2 class="text-md font-medium tracking-[0.25em] uppercase text-slate-400">HopGate</h2>
</div>
<div class="inline-flex items-baseline gap-4 mb-4">
<span class="text-6xl md:text-7xl font-extrabold tracking-[0.25em] text-amber-200">502</span>
<span class="text-lg md:text-xl font-semibold text-slate-100">Bad Gateway</span>
</div>
<p class="text-sm md:text-base text-slate-300 leading-relaxed">
HopGate could not get a valid response from the backend service.<br>
HopGate가 백엔드 서비스로부터 유효한 응답을 받지 못했습니다.
</p>
<div class="mt-8 text-xs md:text-sm text-slate-500">
This may happen when the origin is down, misconfigured, or responding with invalid data.<br>
원본 서버가 다운되었거나 설정이 잘못되었거나, 잘못된 응답을 보내는 경우 발생할 수 있습니다.
</div>
</div>
</body>
</html>