In Go, traditional exception handling mechanisms (like those found in Java or Python) do not exist. Instead, Go uses a combination of error values and panic/recover for error and exception handling. "Throwing an exception" in Go is typically done using the panic function.
panicThe panic function in Go can be used to stop the normal flow of control and begin unwinding the stack. It's a way to signal that something unexpected has happened and the program cannot continue.
Here's how you can "throw an exception" using panic:
panicpackage main
import (
"fmt"
)
func main() {
fmt.Println("Starting the program")
// Trigger a panic
throwException("Something went wrong!")
fmt.Println("This will not be printed")
}
func throwException(message string) {
panic(message)
}
Triggering Panic:
panic(message)
The panic function takes an argument of any type, often a string, which describes the error or exceptional condition.
Unwinding the Stack:
When panic is called, the program prints the panic message and starts to unwind the stack, executing any deferred functions along the way, and eventually terminating the program if not recovered.
recoverTo handle panics and potentially allow the program to continue running, you can use the recover function inside a deferred function. This allows you to catch the panic, handle it, and prevent the program from crashing.
package main
import (
"fmt"
)
func main() {
defer func() {
if err := recover(); err != nil {
fmt.Println("Recovered from panic:", err)
}
}()
fmt.Println("Starting the program")
// Trigger a panic
throwException("Something went wrong!")
fmt.Println("This will not be printed")
}
func throwException(message string) {
panic(message)
}
Deferred Recovery Function:
defer func() {
if err := recover(); err != nil {
fmt.Println("Recovered from panic:", err)
}
}()
This deferred function calls recover to catch any panic that occurs in the main function. If a panic is caught, it prints the panic message and the program can continue running if desired.
Panic and Recovery:
The panic is triggered in throwException and caught by the deferred function in main. This demonstrates how you can "throw" and "catch" exceptions in Go using panic and recover.
In a web server context, you might use panic and recover to handle unexpected errors gracefully without crashing the server:
package main
import (
"fmt"
"net/http"
)
func main() {
http.HandleFunc("/", safeHandler)
http.ListenAndServe(":8080", nil)
}
func safeHandler(w http.ResponseWriter, r *http.Request) {
defer func() {
if err := recover(); err != nil {
http.Error(w, fmt.Sprintf("Internal Server Error: %v", err), http.StatusInternalServerError)
}
}()
// Simulate an unexpected error
throwException("A critical error occurred")
fmt.Fprintln(w, "This will not be printed if panic occurs")
}
func throwException(message string) {
panic(message)
}