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

Projects
None yet
3 participants
@yyrdl
Copy link

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

This comment has been minimized.

Copy link
Member

commented Oct 28, 2016

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

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

@bradfitz bradfitz closed this Oct 28, 2016

@yyrdl

This comment has been minimized.

Copy link
Author

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.
You can’t perform that action at this time.