Skip to content

New web framework design #35378

@wxiaoguang

Description

@wxiaoguang

Design

Let Must functions handle all "internal server errors", let route handlers have return values.

The "panic/recover" is quite fast, not too much slower than "if err" check in real world, much faster than a DB query. And in most cases, the panic won't happen. The code just works as the "panic/recover" doesn't exist.

func Middleware(...) {
    defer func() {
         err := recover()
         if err != nil {
              // ErrNotExist renders 404 page, ErrPermissionDenied renders 403 page, etc, other errors render 500 page
              RenderErrorPage(err)
         }
    }
}

func Handler(ctx *Context) Response {
    user := MustOrNotExist(GetUserByID(uid))
    issue := Must(GetIssueByID(issueID))
    return RenderHTML(user, issue) // or RespondJSON(....)
}

func Must[T](...) T {
    if err != nil {
        panic(WrapMustError(err))
    }
}

"panic" benchmark in real world

  • "recover panic" catch: 140.5 ns/op
  • "if err" check: 77.66 ns/op
func BenchmarkErrorPanic(b *testing.B) {
	foo := func(i int) error {
		return fmt.Errorf("err-%d", i)
	}

	handleErr := func(err error) {
		_ = err
	}

	byPanic := func(i int) {
		defer func() {
			if err := recover().(error); err != nil {
				handleErr(err)
			}
		}()
		if err := foo(i); err != nil {
			panic(err)
		}
	}

	byIfErr := func(i int) {
		err := foo(i)
		if err != nil {
			handleErr(err)
		}
	}

	// BenchmarkErrorPanic/panic-12         	 8230132	       140.5 ns/op
	b.Run("panic", func(b *testing.B) {
		for i := 0; i < b.N; i++ {
			byPanic(i)
		}
	})

	// BenchmarkErrorPanic/error-12         	15548337	        77.66 ns/op
	b.Run("error", func(b *testing.B) {
		for i := 0; i < b.N; i++ {
			byIfErr(i)
		}
	})
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions