GO-Routine stop the main by error


(Marc) #1

If I use a GO-Routine and this Routine makes a Error, break the main. How can I stop this, how can I make it that breaks off only the GO-Routine and not the whole program?


(Lutz Horn) #2

Please include the minimal code required to demonstrate this problem. Maybe create an executable example on https://play.golang.com/.


(Marc) #3

Why? My question is of general interest! I want a tip, with what pattern I counteract this problem!


(Lutz Horn) #4

Because your problem description

this Routine makes a Error, break the main

is so vague, that it is impossible to answer. Please help us helping you by providing a short program that demonstrates the behaviour you observe.


(Marc) #5

Since this problem always occurs when a GORoutine throws an error, it stops the main routine. I’m just trying to understand the package “context.Context”, maybe I can handle it. And since I do not know exactly, I put here so mobile, from the train this question!


(Lutz Horn) #6

Take a look at this sample:

package main

import (
	"fmt"
	"sync"
)

// Breaking is a function that does something that returns an error.
func Breaking(done *sync.WaitGroup, errors chan<- error) {
	defer done.Done()

	fmt.Println("this is a breaking goroutine")

	// This is this error.
	err := fmt.Errorf("goroutine error from Breaking")

	// If the previous operation returned an error, we send it to the error channel.
	if err != nil {
		errors <- err
	}
}

// Working is a function that works.
func Working(done *sync.WaitGroup, errors chan<- error) {
	defer done.Done()

	fmt.Println("this is a working goroutine")

	// There is no error.
	var err error = nil

	// If the previous operation returned an error, we send it to the error channel.
	if err != nil {
		errors <- err
	}
}

func main() {
	errors := make(chan error, 0)
	var done sync.WaitGroup

	done.Add(1)
	go Breaking(&done, errors)

	done.Add(1)
	go Working(&done, errors)

	// For simplicity we only read one error. In a real program we would have
	// to wait for the channel to be closed.
	err := <-errors
	if err != nil {
		fmt.Printf("error received: %q\n", err)
	}

	done.Wait()
}

Output:

this is a working goroutine
this is a breaking goroutine
error received: “goroutine error from Breaking”


(Norbert Melzer) #7

Hmmm… As I understand the OP, he is asking about panics, not some returned or sent error-value.

But I do not think that Go is capable of that. Even though there is some limited panic recovery possible through the defer mechanism, you can’t use it to encapsulate full go routines (or you’ll have to repeat a lot of code).

If you want to have really encapsulated, supervised and independent processes then perhaps the BEAM-ecosystem is better suited?


(Lutz Horn) #8

The problem is that he is not asking an answerable question :slight_smile:


(Norbert Melzer) #9

Yes, the question is understandable the way you did, and the way I did. And perhaps someone else might even see a third question and will try to correct our both understanding of the problem…

So it might really help if @Moo were clarifying their question.


(Sreeramaraju ) #10

There are two ways.

1 - code should not be panicked, so fix your code to not get panic

2 - If above is not possible, use wrapper function with recover around your actual function and call go routine on that wrapper function