Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

runtime: Is it significative and possible to recover(catch) the uncaught error in sub goroutine? #17646

Closed
yyrdl opened this issue Oct 28, 2016 · 2 comments

Comments

@yyrdl
Copy link

yyrdl commented Oct 28, 2016

Please answer these questions before submitting your issue. Thanks!

What version of Go are you using (go version)?

1.7.3

What operating system and processor architecture are you using (go env)?

windows/amd64

What did you do?

If possible, provide a recipe for reproducing the error.
A complete runnable program is good.
A link on play.golang.org is best.

package main

import (
    "fmt"
    "time"
)

/*********TASK************/

type Task struct {
    channel chan bool
    done    bool
}

func (task *Task) Run() {

    time.AfterFunc(time.Second*5, func() { //this callback will run in another goroutine,not the current one
        panic("Manual error")
        task.channel <- true
    })

    <-task.channel

    task.done = true
}
func (task *Task) IsDone() bool {
    return task.done
}

func NewTask() *Task {
    t := new(Task)
    t.channel = make(chan bool, 1)
    t.done = false
    return t
}

/************TRANSACTION***************/

type Transaction struct {
    task   *Task
    is_err bool
}

func (m *Transaction) SetTask(task *Task) {
    m.task = task
}

func (m *Transaction) IsError() bool {
    return m.is_err
}

func (m *Transaction) IsDone() bool {
    return m.task.IsDone()
}

func (m *Transaction) Run() {
    defer func() { //I'd like to catch the error throwed by the task
        //,no matter if the error is occurred in the current goroutine or goroutine created by task.Run and etc.
        //Here , I suppose there is a goroutine tree,the error will spread from the function call stack at first in the current goroutine
        // (can be recovered use defer),and if it is not caught manually in the current gorountine ,it will be spread to the parent.
        //but ,in fact ,it is wrong. And if it is possible and significative to implement this feature?
        if r_c := recover(); r_c != nil {
            m.is_err = true
        }
    }()
    m.task.Run()
}

func NewTransaction() *Transaction {
    m := new(Transaction)
    m.is_err = false
    return m
}

func main() {

    task := NewTask()
    m := NewTransaction()
    m.SetTask(task)
    go m.Run()
    fmt.Println("Task is running")
    for {
        if m.IsDone() || m.IsError() {
            break
        }
    }
    if m.IsError() {
        fmt.Println("Error")
    } else {
        fmt.Println("done")
    }

}

What did you expect to see?

I'd like to caught the error occurred in the child goroutine(There is no child goroutine in Golang).

What did you see instead?

I failed to caught the error. And if it is possible and significative to implement goroutine tree and spread error along the tree?

@bradfitz
Copy link
Contributor

For questions, see https://golang.org/wiki/Questions

Also, all goroutines are independent. There is no hierarchy (no "child" goroutines).

@yyrdl
Copy link
Author

yyrdl commented Oct 29, 2016

thanks for your reply,that'is helpful!

@mikioh mikioh changed the title Is it significative and possible to recover(catch) the uncaught error in sub goroutine? runtime: Is it significative and possible to recover(catch) the uncaught error in sub goroutine? Oct 30, 2016
@golang golang locked and limited conversation to collaborators Oct 30, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants