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

[Question]: New filter run panic #1163

Closed
cyrnicolase opened this issue Dec 7, 2023 · 8 comments
Closed

[Question]: New filter run panic #1163

cyrnicolase opened this issue Dec 7, 2023 · 8 comments
Assignees
Labels
question Further information is requested

Comments

@cyrnicolase
Copy link
Contributor

cyrnicolase commented Dec 7, 2023

I developed a new filter, it's really simple. I used egbuilder init one, and then add some log.

My filter code

package echo

import (
        "fmt"

        egCtx "github.com/megaease/easegress/v2/pkg/context"
        "github.com/megaease/easegress/v2/pkg/filters"
)


const (
        resultEchoFail = "EchoFail"
)

var Kind = &filters.Kind{
        CreateInstance: func(spec filters.Spec) filters.Filter {
                return &Echo{spec: spec.(*Spec)}
        },
        DefaultSpec: func() filters.Spec {
                return &Spec{}
        },
        Description: "Echo is my first filter plugin",
        Name:        "Echo",
        Results:     []string{resultEchoFail},
}

type Echo struct {
        spec *Spec
}

type Spec struct {
        filters.BaseSpec `json:",inline"`
}

var _ filters.Filter = (*Echo)(nil)
var _ filters.Spec = (*Spec)(nil)

func (s *Spec) Validate() error {
        return nil
}

func (e *Echo) Name() string {
    return "Echo"
}

func (e *Echo) Kind() *filters.Kind {
        return Kind
}

func (e *Echo) Spec() filters.Spec {
        return e.spec
}

func (e *Echo) Init() {
    fmt.Println("Call Echo Init func")
}

// Inherit inherits previous filter.
func (e *Echo) Inherit(previousGeneration filters.Filter) {
    fmt.Println("Call Echo Inherit func")
}

// Handle handles the request.
func (e *Echo) Handle(ctx *egCtx.Context) string {
    fmt.Println("Hello my first filter")

        return ""
}

// Status returns the status of the filter.
func (e *Echo) Status() interface{} {
    fmt.Println("Call Echo status func")
        return nil
}

// Close closes the filter.
func (e *Echo) Close() {}

My configuration

name: hs
kind: HTTPServer
port: 10180
http3: false
https: false
keepAlive: true
keepAliveTimeout: 60s
maxConnections: 1024
clientMaxBodySize: 1048576
rules:
  - host: example.org
    paths:
      - backend: pl.example.org

---

name: pl.example.org
kind: Pipeline
flow:
  - filter: echo
  - filter: proxy
filters:
  - name: echo
    kind: Echo

  - name: proxy
    kind: Proxy
    pools:
      - servers:
        - url: http:https://127.0.0.1:8181

I get a panic

图片

My Question

  1. What happend ?
  2. How do I know the exact error ?
@cyrnicolase cyrnicolase added the question Further information is requested label Dec 7, 2023
@suchen-sci
Copy link
Contributor

copy that, i will try to find out what happens.

@suchen-sci
Copy link
Contributor

func (e *Echo) Name() string {
	return e.spec.Name()
}

There is a bug when generate code. Name() method should return name of spec.

@cyrnicolase
Copy link
Contributor Author

It works.

The error message is not clear. Is there any way i can clearly understand the cause of the error ?

@suchen-sci
Copy link
Contributor

p.filters[filter.Name()] = filter

https://github.com/megaease/easegress/blob/main/pkg/object/pipeline/pipeline.go#L292

In flow, the filter name is echo. But in pipeline, the name became Echo. So when do handle, pipeline gets a nil. And a call Handle to nil causes the panic.

I will make a pr to fix the bug and also add some integration tests to make sure the kind of error never happen again!

@cyrnicolase
Copy link
Contributor Author

Thank you very much!

@cyrnicolase
Copy link
Contributor Author

cyrnicolase commented Dec 8, 2023

Sorry , I reopen this issue. I still have a question . As I mentioned above, may I know more accurate error information, not like this:

图片

I can know which filter , where is the bug.

@suchen-sci
Copy link
Contributor

This is a little embarrassing for me.
Usually, Easegress prints error message when meet an error, used for users to debug. For example, for proxy filter, the backend is not exist, or an invalid spec.

In this case, this panic caused by a bug of egbuilder, I am afraid that we usually don't have error messages for a bug. Bug is not want we want, it always happens in an unexpected way. If we know there may be a bug, then we fix it before it cause a problem. So I actually do some diggings to find where cause the problem.

Here is what I do to find this bug, first I update the pipeline yaml, make it only contains one filter of proxy, then I find it works as expected. So, the bug happens in the new filter. Then I do some print in pipeline.go to find why I success to create it but fail to use it. Then I find the problem...

easegress-server expects filter.Name() return same value of spec.Name(). And it is true. The problem caused by egbuilder, it makes a mistake when generates the code.

@cyrnicolase
Copy link
Contributor Author

thanks, I get it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants