From ce9fc3eb02602940cd13205665c1618817a13351 Mon Sep 17 00:00:00 2001 From: Dax Raad Date: Tue, 20 Feb 2024 23:33:35 -0500 Subject: [PATCH] socket support --- cmd/sst/ui/ui.go | 7 ++++ examples/test/src/index.mjs | 1 + .../functions/nodejs-runtime/index.ts | 12 +++--- pkg/server/dev/aws/aws.go | 42 ++++++++++++++----- pkg/server/server.go | 6 +++ pkg/server/socket/socket.go | 11 +++++ 6 files changed, 63 insertions(+), 16 deletions(-) diff --git a/cmd/sst/ui/ui.go b/cmd/sst/ui/ui.go index efa05669c..11ab8adc2 100644 --- a/cmd/sst/ui/ui.go +++ b/cmd/sst/ui/ui.go @@ -402,6 +402,13 @@ func (u *UI) Event(evt *server.Event) { u.printEvent(color.FgGreen, "Build", evt.FunctionBuildEvent.FunctionID) } + if evt.FunctionErrorEvent != nil { + u.printEvent(color.FgRed, "Error", evt.FunctionErrorEvent.ErrorMessage) + for _, item := range evt.FunctionErrorEvent.Trace { + u.printEvent(color.FgRed, "", strings.TrimSpace(item)) + } + } + } func (u *UI) printEvent(barColor color.Attribute, label string, message string) { diff --git a/examples/test/src/index.mjs b/examples/test/src/index.mjs index 8cc47d46b..c985f4a5f 100644 --- a/examples/test/src/index.mjs +++ b/examples/test/src/index.mjs @@ -1,5 +1,6 @@ export async function handler() { console.log("hello"); + throw new Error("test"); return { statusCode: 200, headers: { diff --git a/pkg/platform/functions/nodejs-runtime/index.ts b/pkg/platform/functions/nodejs-runtime/index.ts index 426e818b0..0f34391c5 100644 --- a/pkg/platform/functions/nodejs-runtime/index.ts +++ b/pkg/platform/functions/nodejs-runtime/index.ts @@ -21,7 +21,11 @@ let response: any; let context: LambdaContext; async function error(ex: any) { - console.log(ex); + const body = JSON.stringify({ + errorType: "Error", + errorMessage: ex.message, + trace: ex.stack?.split("\n"), + }); await fetch( AWS_LAMBDA_RUNTIME_API + (!context @@ -32,11 +36,7 @@ async function error(ex: any) { headers: { "Content-Type": "application/json", }, - body: JSON.stringify({ - errorType: "Error", - errorMessage: ex.message, - trace: ex.stack?.split("\n"), - }), + body, }, ); } diff --git a/pkg/server/dev/aws/aws.go b/pkg/server/dev/aws/aws.go index 786781062..25c32cc45 100644 --- a/pkg/server/dev/aws/aws.go +++ b/pkg/server/dev/aws/aws.go @@ -51,6 +51,15 @@ type FunctionResponseEvent struct { Output []byte } +type FunctionErrorEvent struct { + FunctionID string + WorkerID string + RequestID string + ErrorType string `json:"errorType"` + ErrorMessage string `json:"errorMessage"` + Trace []string `json:"trace"` +} + type FunctionBuildEvent struct { FunctionID string Errors []string @@ -178,9 +187,10 @@ func Start( fileChan := make(chan *watcher.FileChangedEvent, 1000) type workerResponse struct { - response *http.Response - workerID string - path []string + response *http.Response + requestBody *bytes.Buffer + workerID string + path []string } workerResponseChan := make(chan workerResponse, 1000) workerShutdownChan := make(chan *WorkerInfo, 1000) @@ -287,7 +297,7 @@ func Start( continue } - body, err := io.ReadAll(evt.response.Body) + responseBody, err := io.ReadAll(evt.response.Body) if err != nil { continue } @@ -297,7 +307,7 @@ func Start( FunctionID: info.FunctionID, WorkerID: info.WorkerID, RequestID: info.CurrentRequestID, - Input: body, + Input: responseBody, }) } if evt.path[len(evt.path)-1] == "response" { @@ -305,9 +315,18 @@ func Start( FunctionID: info.FunctionID, WorkerID: info.WorkerID, RequestID: evt.path[len(evt.path)-2], - Output: body, + Output: responseBody, }) } + if evt.path[len(evt.path)-1] == "error" { + fee := &FunctionErrorEvent{ + FunctionID: info.FunctionID, + WorkerID: info.WorkerID, + RequestID: evt.path[len(evt.path)-2], + } + json.Unmarshal(evt.requestBody.Bytes(), &fee) + bus.Publish(fee) + } case info := <-workerShutdownChan: slog.Info("worker died", "workerID", info.WorkerID) existing, ok := workers[info.WorkerID] @@ -404,8 +423,10 @@ func Start( fmt.Fprint(writer, "Host: 127.0.0.1\r\n") _, err := fmt.Fprint(writer, "\r\n") + requestBody := &bytes.Buffer{} if r.ContentLength > 0 { - io.Copy(writer, r.Body) + write := io.MultiWriter(writer, requestBody) + io.Copy(write, r.Body) } writer.Flush() @@ -435,9 +456,10 @@ func Start( resp, err := http.ReadResponse(bufio.NewReader(buf), nil) if err == nil { workerResponseChan <- workerResponse{ - workerID: workerID, - response: resp, - path: path, + workerID: workerID, + response: resp, + requestBody: requestBody, + path: path, } } done <- struct{}{} diff --git a/pkg/server/server.go b/pkg/server/server.go index 20505f6a4..d5581de42 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -39,6 +39,7 @@ type Event struct { StateEvent *StateEvent FunctionInvokedEvent *aws.FunctionInvokedEvent FunctionResponseEvent *aws.FunctionResponseEvent + FunctionErrorEvent *aws.FunctionErrorEvent FunctionLogEvent *aws.FunctionLogEvent FunctionBuildEvent *aws.FunctionBuildEvent } @@ -122,6 +123,11 @@ func (s *Server) Start(parentContext context.Context) error { FunctionResponseEvent: event, }) }) + bus.Subscribe(ctx, func(event *aws.FunctionErrorEvent) { + publish(&Event{ + FunctionErrorEvent: event, + }) + }) bus.Subscribe(ctx, func(event *aws.FunctionLogEvent) { publish(&Event{ diff --git a/pkg/server/socket/socket.go b/pkg/server/socket/socket.go index 618d85da6..7d5660188 100644 --- a/pkg/server/socket/socket.go +++ b/pkg/server/socket/socket.go @@ -61,6 +61,7 @@ func Start(ctx context.Context, p *project.Project, mux *http.ServeMux) { invoke := bus.Listen(ctx, &aws.FunctionInvokedEvent{}) response := bus.Listen(ctx, &aws.FunctionResponseEvent{}) + error := bus.Listen(ctx, &aws.FunctionErrorEvent{}) log := bus.Listen(ctx, &aws.FunctionLogEvent{}) stack := bus.Listen(ctx, &project.StackEvent{}) @@ -145,6 +146,16 @@ func Start(ctx context.Context, p *project.Project, mux *http.ServeMux) { publishInvocation(invocation) } break + case evt := <-error: + invocation, ok := invocations[evt.RequestID] + if ok { + invocation.End = time.Now().UnixMilli() + invocation.Report = &InvocationReport{ + Duration: invocation.End - invocation.Start, + } + publishInvocation(invocation) + } + break case evt := <-log: invocation, ok := invocations[evt.RequestID] if ok {