# Handling Errors in Golang

Errors in golang are vastly different from errors in JavaScript. In this post, we will implement error handling for the  [events project](https://github.com/iroegbu/golang-tut-events) we started building in the  [first post](https://iroegbu.com/go-for-nodejs-developers) . That means, handling errors within the module itself as well as errors from event listeners.

First thing of note, with errors in golang is that errors are values not events. In JavaScript, errors (or Exceptions) are things that happen (events) that you need to  [`catch`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch)  and react to. In golang, errors are returned and you use them as values to make decisions. See  [this tutorial](https://gobyexample.com/errors) for more details on error handling.

## Implementation

For the problem we are trying to solve ( [see first post](https://iroegbu.com/go-for-nodejs-developers), we will have to implement a special `error` event with a single listener that will print out the error and exit the application; this listener will get overwritten if the user creates a listener for errors.
```
func (ee EventEmitter) emit(event string, args ...interface{}) {
	if event == "error" {
		if _, ok := ee.events[event]; ok == false {
			fmt.Println(args...)
			panic("no listener registered")
		}
	}

	if e, ok := ee.events[event]; ok {
		for _, listener := range e.listeners {
			_, err := listener(args)
			if err != nil {
				ee.emit("error", err)
			}
		}
	}
}
```
We have updated the `emit` method to cater for when the error event is emitted without a listener being registered. We have also modified the signature for listeners; included return types and allow listeners to take any types (not just strings as before). This means we can check for when listeners return errors and emit the `error` event.

## Usage

First thing is to implement a listener for error events, this is because we don't want the application to exit whenever an error is returned from a listener.
```
var errorHandler = func(args ...interface{}) (interface{}, error) {
	errors := args[0].([]interface{})
	for _, error := range errors {
		fmt.Println("ERROR!", error)
	}
	return nil, nil
}
```
This listener needs to be registered within the server initialization  method
```
func (server server) init() {
	// Register all listeners
	server.eventsEmitter.on("connect", handleConnection)
	server.eventsEmitter.on("connect", logMessage)
	server.eventsEmitter.on("data", logMessage)
	server.eventsEmitter.on("error", errorHandler)
	server.eventsEmitter.on("disconnect", handleDisonnection)
}
```
Next, to trigger the error event, we modify the `handleDisconnection` listener to always return an error, this will help us test the `error` event.
```
var handleDisonnection = func(args ...interface{}) (interface{}, error) {
	return nil, errors.New("failed to disconnect")
}
```

When you run this program, all the listeners are triggered as before. But, this time instead of the message for disconnection we get the message for error in disconnection

```
http/connection/string Connected successfully
2021/12/29 15:10:40 Connected successfully
2021/12/29 15:10:40 Message from user 1
2021/12/29 15:10:40 Message from user 2
2021/12/29 15:10:40 Message from user 3
2021/12/29 15:10:40 Message from user 4
ERROR! failed to disconnect
```
*Note that we have modified all listeners to follow the new signatures*

## Next Steps
We still have some unresolved issues with this library, I'll be updating the [Github project](https://github.com/iroegbu/golang-tut-events/projects/1) with improvements as I think of them. 
