Golang Error Handling Dengan Framework Echo.
Tags: go, labstack, echo, errors
Published: 2022-09-25 02:44:21

**J**ika kalian pernah menulis kode dengan bahasa pemrograman golang, penulisan error handling akan sangat berbeda sekali dengan beberapa bahasa pemrograman populer yang lain, hal ini membuat sebagian programmer kebingungan memilih pendekatan untuk mengimplementasikan error handling yang tepat.

> Disclaimer: artikel ini untuk kalian yang sudah pengalaman menggunakan golang pembahasan ini hanya untuk framework echo dan hanya sebagai referensi error handling. Bagi yang belum paham apa itu error handling silahkan belajar basic dahulu CMIIW :)

---

Saat ini saya menggunakan Framework Echo, bagaimana untuk mengimplementasi Error Handling di echo? sebelum itu kita harus tahu dulu bahwa tipe data error pada golang bertipe interface, oleh karena itu kita bisa membuat juga custom implementasi dari tipe data error.

{% embed https://go.dev/tour/methods/19 %}

``` go
package exceptions

type BadRequestErrorStruct struct {
	ErrorMsg string
}

func NewBadRequestError(msg string) *BadRequestErrorStruct {
	return &BadRequestErrorStruct{
		ErrorMsg: msg,
	}
}

func (e *BadRequestErrorStruct) Error() string {
	return e.ErrorMsg
}
```

Contoh diatas merupakan implementasi dari tipe data error di golang, untuk membuat error kita hanya memanggil fungsi NewBadRequestError(), ini memerlukan inputan berupa pesan error.

Echo sebenarnya sudah membuat default Error Handling nya, akan tetapi kebutuhan pengguna itu berbeda-beda, maka dari itu kita di mudahkan untuk membuat Error Handling secara Custom.

{% embed https://echo.labstack.com/guide/error-handling %}

Fungsi echo.HTTPErrorHandling adalah default Error Handling dari echo, untuk membuatnya custom kita cukup menimpanya dengan fungsi buatan sendiri.

``` go
package handler

import (
	"net/http"

	"github.com/labstack/echo/v4"
)


/*
	Fungsi untuk membuat custom error.
*/
func CustomErrorHandling(err error, c echo.Context) {
	if notFoundError(err, c) {
		return
	} else if badRequestError(err, c) {
		return
	} else if forbiddenError(err, c) {
		return
	} else {
		internalServerError(err, c)
		return
	}
}
```

Line 13–24, merupakan fungsi implementasi dari *echo.HTTPErrorHandling*, fungsi tersebut memerlukan 2 input parameter yakni error dan echo.Context.

> Error, digunakan untuk mengidentifikasi error apakah yang menimpa kodenya. nantinya akan di kembalikan menjadi response error yang sesuai.

> echo.Context, digunakan untuk membuat response yang akan mengembalikan http response.

Di dalam, fungsi *CustomErrorHandling*, saya membuat pengecekan setiap error yang dihadapi, hal ini bertujuan untuk mengidentifikasi jenis error apa yang cocok untuk di kembalikan ke *http response*.

``` go
func internalServerError(err error, c echo.Context) bool {
	response, ok := err.(*exceptions.InternalServerErrorStruct)
	if ok {
		c.JSON(http.StatusInternalServerError, map[string]interface{}{
			"success": false,
			"message": response.Error(),
		})
		return true
	}
	return false
}

func badRequestError(err error, c echo.Context) bool {
	response, ok := err.(*exceptions.BadRequestErrorStruct)
	if ok {
		c.JSON(http.StatusBadRequest, map[string]interface{}{
			"success": false,
			"message": response.Error(),
		})
		return true
	}
	return false
}

func notFoundError(err error, c echo.Context) bool {
	response, ok := err.(*exceptions.NotFoundErrorStruct)
	if ok {
		c.JSON(http.StatusNotFound, map[string]interface{}{
			"success": false,
			"message": response.Error(),
		})
		return true
	}
	return false
}

func forbiddenError(err error, c echo.Context) bool {
	response, ok := err.(*exceptions.ForbiddenErrorStruct)
	if ok {
		c.JSON(http.StatusForbidden, map[string]interface{}{
			"success": false,
			"message": response.Error(),
		})
		return true
	}
	return false
}
```

Kumpulan fungsi diatas merupakan implementasi dari pengecekan di fungsi *CustomErrorHandling*.


Setiap fungsi tersebut, akan melakukan [type assertion](https://go.dev/tour/methods/15), kita sudah tahu bahwa tipe data error merupakan sebuah interface, oleh karena itu perlu menegaskan implementasi yang mana cocok dengan error tersebut, ketika kondisi terpenuhi maka akan mengembalikan _http response_ kepada user, terkait kondisi error apa yang di terima.

## Penjelasan dan pembuatan fungsi custom error handling sudah selesai, lantas gimana cara penggunaanya?

Untuk menggunakannya kita perlu membuat service dahulu.

```go
func ErrorService(c echo.Context) error {
	/*
		Ambil query parameter dengan key "error"
	*/
	errorParam := c.QueryParam("error")

	switch errorParam {
	case "internal server error":
		return exceptions.NewInternalServerError(errorParam)
	case "bad request":
		return exceptions.NewBadRequestError(errorParam)
	case "not found":
		return exceptions.NewNotFoundError(errorParam)
	case "forbidden":
		return exceptions.NewForbiddenError(errorParam)
	}

	return c.JSON(http.StatusOK, map[string]interface{}{
		"success": true,
		"message": "no error occured",
	})
}
```

Untuk simulasi service, saya hanya menggunakan *queryParam*, yang akan di lakukan pengecekan setiap apa pun nanti isi dari variabel *errorParam*, Nah, di dalam pengkondisian tersebut, memanggil fungsi custom yang mengimplemetasi interface error, dengan input sebuah parameter pesan error yang akan di kirim.

Untuk di fungsi main.go

```go
func main() {
	/*
		Inisialisasi framework echo
	*/
	e := echo.New()

	/*
		Timpa fungsi HTTPErrorHandler dari echo,
		menggunakan custom errorHandler buatan sendiri.
	*/
	e.HTTPErrorHandler = handler.CustomErrorHandling

	/*
		Untuk mengabaikan ketika terjadi sebuah error.
	*/
	e.Use(middleware.Recover())

	e.GET("/service", handler.ErrorService)

	err := e.Start(":8080")
	if err != nil {
		log.Fatal(err)
	}
}
```

Seperti biasa, fungsi main untuk inisialisasi frameworknya.

Perhatikan di line 11, saya menimpa *echo.HTTPErrorHandler* dengan fungsi *CustomErrorHandling* yang sudah saya buat tadi, hal ini dapat merubah perilkaku *error handling* di echo.

Kemudian di line 28, saya berikan sebuah *middleware* untuk menanggulangi terjadinya *panic*, akan segera menghidupkan server kembali.

Untuk hasilnya kurang lebih nanti akan seperti ini.

Untuk Source Code lengkapnya bisa di mengunjungi :
{% embed https://gitlab.com/havisikkubaru/echo-error-handler %}

## Kesimpulan
Dalam bahasa pemrograman golang terutama untuk Error Handling banyak sekali pendekatannya, untuk itu pakai pendekatan yang sesuai dengan kebutuhan dan perhatikan kebersihan kodenya juga. Apakah mudah di baca atau tidak.

---

#Reading is one way to speed up gaining knowledge from someone experience ~ someone