recover 사용하기
Coddy GO 여정의 로직 & 흐름 섹션에 포함된 레슨 — 68개 중 43번째.
panic이 프로그램을 즉시 중단시키지만, Go는 recover 함수를 통해 제어권을 다시 얻는 방법을 제공합니다. recover 함수를 사용하면 패닉을 포착하고 이를 정상적으로 처리하여 전체 프로그램이 충돌하는 것을 방지할 수 있습니다.
하지만 recover에는 매우 구체적인 요구 사항이 있습니다. 이는 지연된(deferred) 함수 내부에서만 사용할 수 있습니다. 패닉(panic)이 발생하면 Go는 프로그램이 종료되기 전에 모든 지연된 함수를 실행하여 recover가 패닉을 가로챌 수 있는 기회를 제공합니다:
func riskyFunction() {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered from panic:", r)
}
}()
panic("something went wrong!")
}recover 함수는 panic에 전달된 값을 반환하거나, 패닉이 발생하지 않은 경우 nil을 반환합니다. 이를 통해 패닉 발생 여부를 확인하고 에러 로깅이나 정리 작업 수행과 같은 적절한 조치를 취할 수 있습니다.
panic과 마찬가지로, recover는 Go에서 드물게 사용되어야 합니다. 이는 단일 요청의 패닉이 전체 서버를 중단시키는 것을 방지하고, 서버가 다른 요청을 계속 처리할 수 있도록 하려는 웹 서버와 같은 시나리오에서 가장 흔히 볼 수 있습니다.
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
챌린지
쉬움recover를 사용하여 패닉을 우아하게 처리하고 전체 서버가 중단되는 것을 방지하는 웹 서버 요청 핸들러를 구축하세요. 이 챌린지는 패닉을 포착하고 서버 안정성을 유지하기 위해 지연된 함수(deferred function) 내에서 recover를 사용하는 방법을 보여줍니다.
두 개의 입력을 받게 됩니다:
"endpoint,method,action"형식의 요청 세부 정보가 포함된 문자열 (예:"/api/users,GET,process")"server_name,max_requests"형식의 서버 설정이 포함된 문자열 (예:"WebServer,100")
수행할 작업은 다음과 같습니다:
- 첫 번째 입력을 쉼표로 분리하여 endpoint, method, action을 파싱합니다.
- 두 번째 입력을 쉼표로 분리하여 server name과 max requests를 파싱합니다.
- max requests 문자열을 정수로 변환합니다.
- endpoint, method, action, server name을 매개변수로 받는
handleRequest함수를 생성합니다. handleRequest내부에recover를 사용하여 패닉을 포착하는 지연된 함수(deferred function)를 추가합니다:- 패닉이 복구되면(recover가 non-nil을 반환하면), 다음을 출력합니다:
"Server [server_name] recovered from panic: [panic_value]" - 패닉을 처리한 후, 다음을 출력합니다:
"Request handling completed safely"
- 패닉이 복구되면(recover가 non-nil을 반환하면), 다음을 출력합니다:
- 지연된 함수 다음에 action에 따라 요청 처리를 시뮬레이션합니다:
- action이
"process"인 경우:"Processing [method] request to [endpoint]"를 출력합니다. - action이
"panic_nil"인 경우:"Attempting dangerous operation"을 출력한 다음panic("nil pointer access")를 호출합니다. - action이
"panic_overflow"인 경우:"Attempting resource allocation"을 출력한 다음panic("memory overflow")를 호출합니다. - action이
"panic_timeout"인 경우:"Attempting database connection"을 출력한 다음panic("connection timeout")를 호출합니다. - 그 외의 action인 경우:
"Unknown action: [action]"을 출력한 다음panic("invalid action")을 호출합니다.
- action이
- main 함수에서 서버 시작 메시지를 출력합니다:
"Starting [server_name] with max [max_requests] requests" - 파싱된 매개변수를 사용하여
handleRequest함수를 호출합니다. - 함수 호출 후, 서버 상태를 출력합니다:
"Server [server_name] is still running" - 마지막으로 요약을 출력합니다:
"Server Summary:""Name: [server_name]""Max Requests: [max_requests]""Last Request: [method] [endpoint]""Action Performed: [action]""Status: Operational"
입력 문자열을 쉼표로 분리하려면 strings 패키지를 사용하고, max requests 문자열을 정수로 변환하려면 strconv 패키지를 사용하세요. 이 챌린지는 recover를 통해 서버가 예기치 않은 패닉을 우아하게 처리하여 개별 요청의 실패가 전체 시스템을 중단시키지 않도록 하는 방법을 보여줍니다.
치트 시트
recover 함수를 사용하면 패닉(panic)을 포착하고 이를 정상적으로 처리하여 프로그램이 중단되는 것을 방지할 수 있습니다.
recover는 지연된(deferred) 함수 내부에서만 사용할 수 있습니다:
func riskyFunction() {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered from panic:", r)
}
}()
panic("something went wrong!")
}recover 함수는 panic에 전달된 값을 반환하거나, 패닉이 발생하지 않은 경우 nil을 반환합니다. 이를 통해 패닉 발생 여부를 확인하고 적절한 조치를 취할 수 있습니다.
recover는 웹 서버에서 단일 요청의 패닉이 전체 서버를 중단시키는 것을 방지하기 위해 흔히 사용됩니다.
직접 해보기
package main
import (
"fmt"
"strconv"
"strings"
)
func main() {
// 입력 읽기
var requestDetails string
var serverConfig string
fmt.Scanln(&requestDetails)
fmt.Scanln(&serverConfig)
// 요청 세부 정보 파싱
requestParts := strings.Split(requestDetails, ",")
endpoint := requestParts[0]
method := requestParts[1]
action := requestParts[2]
// 서버 구성 파싱
configParts := strings.Split(serverConfig, ",")
serverName := configParts[0]
maxRequests, _ := strconv.Atoi(configParts[1])
// TODO: 아래에 코드를 작성하세요
// 복구 메커니즘을 포함한 handleRequest 함수 생성
// 서버 시작 메시지 출력
// handleRequest 함수 호출
// 서버 상태 및 요약 출력
}이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
로직 & 흐름의 모든 레슨
7에러 처리 심화
사용자 정의 에러 타입%w를 사용한 에러 래핑errors.Is를 사용한 언래핑errors.As를 사용한 언래핑panic 이해하기recover 사용하기요약 - 안전한 나눗셈