handle_errors 지시문
handle_errors 지시문 (에러 핸들러 설정)
handle_errors 지시문은 에러 핸들러를 설정해요. 일반 HTTP 요청 핸들러가 에러를 반환하면 일반 처리가 중단되고 에러 핸들러가 호출돼요. 정적 에러 페이지, 템플릿 에러 페이지, 또는 다른 백엔드로 리버스 프록시해 에러를 처리할 수 있어요.
출처: Caddy 공식 문서
본문
에러 핸들러를 설정해요.
일반 HTTP 요청 핸들러가 에러를 반환하면 일반 처리가 중단되고 에러 핸들러가 호출돼요. 에러 핸들러는 일반 라우트와 똑같은 라우트를 이루며, 일반 라우트가 할 수 있는 모든 것을 할 수 있어요. 이는 HTTP 요청 중 에러를 처리할 때 큰 제어와 유연성을 제공해요. 예를 들어 정적 에러 페이지, 템플릿 에러 페이지를 서빙하거나, 다른 백엔드로 리버스 프록시해서 에러를 처리할 수 있어요.
다른 상태 코드를 다르게 처리하려면 지시문을 반복할 수 있어요. 상태 코드를 지정하지 않으면 어떤 에러든 매칭하며, 다른 에러 핸들러가 매칭되지 않을 때 폴백으로 동작해요.
요청의 context는 에러 라우트로 이어져요. 그래서 site root나 vars처럼 요청 context에 설정된 값은 에러 핸들러에서도 보존돼요. 또한 에러를 처리할 때 새로운 placeholder도 사용할 수 있어요.
에러로 분류되는 HTTP 상태로 응답을 쓸 수 있는 reverse_proxy 같은 특정 지시문은 에러 라우트를 트리거하지 않아요.
자신의 라우팅 결정에 따라 에러를 명시적으로 트리거하려면 error 지시문을 사용할 수 있어요.
문법 (Syntax)
handle_errors [<status_codes...>] {
<directives...>
}
-
**<status_codes...>**는 처리 중인 에러에 매칭할 하나 이상의 HTTP 상태 코드예요. 상태 코드는 3자리 숫자이거나, 각각 400-499 또는 500-599 범위의 모든 상태 코드에 매칭하는 특수한
4xx또는5xx일 수 있어요. 상태 코드를 지정하지 않으면 어떤 에러든 매칭하며, 다른 에러 핸들러가 매칭되지 않을 때 폴백으로 동작해요. -
**<directives...>**는 한 줄에 하나씩 나열하는 HTTP 핸들러 지시문 및 matcher 목록이에요.
Placeholders
에러를 처리하는 동안 다음 placeholder를 사용할 수 있어요. 이것들은 HTTP 서버 에러 라우트의 JSON 문서에서 찾을 수 있는 전체 placeholder의 Caddyfile 약어예요.
| Placeholder | 설명 (Description) |
|---|---|
{err.status_code} |
권장 HTTP 상태 코드 |
{err.status_text} |
권장 상태 코드와 연결된 상태 텍스트 |
{err.message} |
에러 메시지 |
{err.trace} |
에러의 출처 |
{err.id} |
이 에러 발생에 대한 식별자 |
예시 (Examples)
상태 코드에 기반한 커스텀 에러 페이지(예: 404 에러에 대해 404.html 페이지). handle_errors에서 실행될 때 file_server는 에러의 HTTP 상태 코드를 보존한다는 점에 유의해요(사이트에 site root를 미리 설정했다고 가정):
handle_errors {
rewrite /{err.status_code}.html
file_server
}
templates를 사용해 커스텀 에러 메시지를 쓰는 단일 에러 페이지:
handle_errors {
rewrite /error.html
templates
file_server
}
일부 에러 코드에만 커스텀 에러 페이지를 제공하고 싶다면, file matcher로 커스텀 에러 파일의 존재를 미리 확인할 수 있어요:
handle_errors {
@custom_err file /err-{err.status_code}.html /err.html
handle @custom_err {
rewrite {file_match.relative}
file_server
}
respond "{err.status_code} {err.status_text}"
}
HTTP 에러 처리에 매우 능숙한 전문 서버로 리버스 프록시해서 하루를 더 즐겁게 보내봐요 😸:
handle_errors {
rewrite /{err.status_code}
reverse_proxy https://http.cat {
replace_status {err.status_code}
}
}
respond를 사용해 에러 코드와 이름을 반환하는 간단한 예:
handle_errors {
respond "{err.status_code} {err.status_text}"
}
특정 에러 코드를 다르게 처리하려면:
handle_errors 404 410 {
respond "It's a 404 or 410 error!"
}
handle_errors 5xx {
respond "It's a 5xx error."
}
handle_errors {
respond "It's another error"
}
위는 상태 코드에 대해 expression matcher를 사용하고 상호 배타성을 위해 handle을 사용하는 아래와 동일하게 동작해요:
handle_errors {
@404-410 `{err.status_code} in [404, 410]`
handle @404-410 {
respond "It's a 404 or 410 error!"
}
@5xx `{err.status_code} >= 500 && {err.status_code} < 600`
handle @5xx {
respond "It's a 5xx error."
}
handle {
respond "It's another error"
}
}