Skip to content

Conversation

tiancaiamao
Copy link
Contributor

var err *MyErr
e1 := errors.Trace(err)
e2 := errors.Cause(e1)
e2 != nil    // Isn't it beyond the normal comprehension?

We should never errors.Trace(xxx) when xxx is other than error type.

====================== TL;DR ===============

The minimal runnable code to demonstrate the problem:

package main

import "github.com/juju/errors"

func main() {
	var err *MyErr
	e1 := errors.Trace(err)
	e2 := errors.Cause(e1)
	if e2 != nil {
		panic(e2)
	}
}

type MyErr struct {
}

func (e *MyErr) Error() string {
	return ""
}

The problem is the interface conversion, if we pass a *MyErr type with value nil to this function

func Trace(e error) error { return e }

It's returns a error interface, which is not nil with type *MyErr, the underlying value is nil however.
This kind of data is toxic. It's easy to trap here:

if xxx, ok := e.(*MyErr); ok {
    xxx.doSomething()   // BOOM !!!
}

So the simple rule: We should never errors.Trace(xxx) when xxx is other than error type.
B.T.W, this kind of code is also dangerous:

func f() error {
    var e *MyError
    // ..... e is nil
    return e
}

@coocood @shenli

	var err *MyErr
	e1 := errors.Trace(err)
	e2 := errors.Cause(e1)
	e2 != nil    // Isn't it beyond the normal comprehension?

We should never errors.Trace(xxx) when xxx is other than error type
@tiancaiamao
Copy link
Contributor Author

@zimulala

@@ -464,7 +464,10 @@ func (d *ddl) doDDLJob(ctx context.Context, job *model.Job) error {
return nil
}

return errors.Trace(historyJob.Error)
if historyJob.Error != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this doesn't a good way to handle this problem.
If historyJob isn't synced, the historyJob's Error mustn't be nil. So I think something wrong with the operation of running DDL job.

Copy link
Contributor Author

@tiancaiamao tiancaiamao Jan 30, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just change one line, where I think the error handling could be improved.
I think We should never errors.Trace(xxx) when xxx is other than error type..

Maybe I use the wrong presentation, this have nothing to do with fix, I just want to make the code more robust. So is that acceptable? @zimulala

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No.
I think historyJob's Error is nil is also a problem.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Relate to #5751

@tiancaiamao
Copy link
Contributor Author

/run-all-tests

@tiancaiamao tiancaiamao changed the title ddl: fix an improper error handling ddl: improve an error handling Jan 31, 2018
@zimulala
Copy link
Contributor

LGTM

1 similar comment
@coocood
Copy link
Member

coocood commented Jan 31, 2018

LGTM

@coocood coocood added the status/LGT2 Indicates that a PR has LGTM 2. label Jan 31, 2018
@coocood
Copy link
Member

coocood commented Jan 31, 2018

/run-all-tests

@tiancaiamao tiancaiamao merged commit 7fc2794 into pingcap:master Jan 31, 2018
@tiancaiamao tiancaiamao deleted the ddl-error-handle branch January 31, 2018 08:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status/LGT2 Indicates that a PR has LGTM 2.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants