diff --git a/handler.go b/handler.go index 61930e1..446fb18 100644 --- a/handler.go +++ b/handler.go @@ -20,18 +20,21 @@ var ( func init() { var handleRequestCallback js.Func handleRequestCallback = js.FuncOf(func(this js.Value, args []js.Value) any { - if len(args) > 1 { - panic(fmt.Errorf("too many args given to handleRequest: %d", len(args))) - } reqObj := args[0] var cb js.Func cb = js.FuncOf(func(_ js.Value, pArgs []js.Value) any { defer cb.Release() resolve := pArgs[0] + reject := pArgs[1] go func() { + if len(args) > 1 { + reject.Invoke(jsutil.Errorf("too many args given to handleRequest: %d", len(args))) + return + } res, err := handleRequest(reqObj) if err != nil { - panic(err) + reject.Invoke(jsutil.Error(err.Error())) + return } resolve.Invoke(res) }() @@ -58,7 +61,7 @@ func handleRequest(reqObj js.Value) (js.Value, error) { } req, err := jshttp.ToRequest(reqObj) if err != nil { - panic(err) + return js.Value{}, err } ctx := runtimecontext.New(context.Background(), reqObj) req = req.WithContext(ctx) @@ -90,7 +93,5 @@ func Serve(handler http.Handler) { } httpHandler = handler ready() - select { - case <-closeCh: - } + <-closeCh } diff --git a/internal/jsutil/jsutil.go b/internal/jsutil/jsutil.go index 1175029..e93a0af 100644 --- a/internal/jsutil/jsutil.go +++ b/internal/jsutil/jsutil.go @@ -34,6 +34,14 @@ func NewPromise(fn js.Func) js.Value { return PromiseClass.New(fn) } +func Error(msg string) js.Value { + return ErrorClass.New(msg) +} + +func Errorf(format string, args ...any) js.Value { + return ErrorClass.New(fmt.Sprintf(format, args...)) +} + // ArrayFrom calls Array.from to given argument and returns result Array. func ArrayFrom(v js.Value) js.Value { return ArrayClass.Call("from", v) diff --git a/internal/jsutil/stream.go b/internal/jsutil/stream.go index ed4b4b0..79f5e51 100644 --- a/internal/jsutil/stream.go +++ b/internal/jsutil/stream.go @@ -134,8 +134,7 @@ func (rs *readerToReadableStream) Pull(controller js.Value) error { return nil } if err != nil { - jsErr := ErrorClass.New(err.Error()) - controller.Call("error", jsErr) + controller.Call("error", Error(err.Error())) if err := rs.reader.Close(); err != nil { return err } @@ -170,7 +169,7 @@ func ConvertReaderToReadableStream(reader io.ReadCloser) js.Value { go func() { err := stream.Pull(controller) if err != nil { - reject.Invoke(ErrorClass.New(err.Error())) + reject.Invoke(Error(err.Error())) return } resolve.Invoke() @@ -180,11 +179,22 @@ func ConvertReaderToReadableStream(reader io.ReadCloser) js.Value { return NewPromise(cb) })) rsInit.Set("cancel", js.FuncOf(func(js.Value, []js.Value) any { - err := stream.Cancel() - if err != nil { - panic(err) - } - return js.Undefined() + var cb js.Func + cb = js.FuncOf(func(this js.Value, pArgs []js.Value) any { + defer cb.Release() + resolve := pArgs[0] + reject := pArgs[1] + go func() { + err := stream.Cancel() + if err != nil { + reject.Invoke(Error(err.Error())) + return + } + resolve.Invoke() + }() + return js.Undefined() + }) + return NewPromise(cb) })) return ReadableStreamClass.New(rsInit) }