diff --git a/server/errors.go b/server/errors.go new file mode 100644 index 00000000..31e0faf6 --- /dev/null +++ b/server/errors.go @@ -0,0 +1,25 @@ +package server + +import ( + "fmt" + + "github.com/Layr-Labs/eigenda-proxy/commitments" +) + +// MetaError includes both an error and commitment metadata +type MetaError struct { + Err error + Meta commitments.CommitmentMeta +} + +func (me MetaError) Error() string { + return fmt.Sprintf("Error: %s (Mode: %s, CertVersion: %b)", + me.Err.Error(), + me.Meta.Mode, + me.Meta.CertVersion) +} + +// NewMetaError creates a new MetaError +func NewMetaError(err error, meta commitments.CommitmentMeta) MetaError { + return MetaError{Err: err, Meta: meta} +} diff --git a/server/server.go b/server/server.go index 862ac9e9..1db046db 100644 --- a/server/server.go +++ b/server/server.go @@ -66,9 +66,18 @@ func WithMetrics(handleFn func(http.ResponseWriter, *http.Request) (commitments. recordDur := m.RecordRPCServerRequest(r.Method) meta, err := handleFn(w, r) + if err != nil { + var metaErr MetaError + if errors.As(err, &metaErr) { + recordDur(w.Header().Get("status"), string(metaErr.Meta.Mode), string(metaErr.Meta.CertVersion)) + } else { + recordDur(w.Header().Get("status"), string("NoCommitmentMode"), string("NoCertVersion")) + } + return err + } // we assume that every route will set the status header recordDur(w.Header().Get("status"), string(meta.Mode), string(meta.CertVersion)) - return err + return nil } } @@ -155,14 +164,17 @@ func (svr *Server) HandleGet(w http.ResponseWriter, r *http.Request) (commitment if err != nil { err = fmt.Errorf("invalid commitment mode: %w", err) svr.WriteBadRequest(w, err) - return meta, err + return commitments.CommitmentMeta{}, err } key := path.Base(r.URL.Path) comm, err := commitments.StringToDecodedCommitment(key, meta.Mode) if err != nil { err = fmt.Errorf("failed to decode commitment from key %v (commitment mode %v): %w", key, meta.Mode, err) svr.WriteBadRequest(w, err) - return meta, err + return commitments.CommitmentMeta{}, MetaError{ + Err: err, + Meta: meta, + } } input, err := svr.router.Get(r.Context(), comm, meta.Mode) @@ -173,7 +185,10 @@ func (svr *Server) HandleGet(w http.ResponseWriter, r *http.Request) (commitment } else { svr.WriteInternalError(w, err) } - return meta, err + return commitments.CommitmentMeta{}, MetaError{ + Err: err, + Meta: meta, + } } svr.WriteResponse(w, input) @@ -189,14 +204,17 @@ func (svr *Server) HandlePut(w http.ResponseWriter, r *http.Request) (commitment if err != nil { err = fmt.Errorf("invalid commitment mode: %w", err) svr.WriteBadRequest(w, err) - return meta, err + return commitments.CommitmentMeta{}, err } input, err := io.ReadAll(r.Body) if err != nil { err = fmt.Errorf("failed to read request body: %w", err) svr.WriteBadRequest(w, err) - return meta, err + return commitments.CommitmentMeta{}, MetaError{ + Err: err, + Meta: meta, + } } key := path.Base(r.URL.Path) @@ -207,7 +225,10 @@ func (svr *Server) HandlePut(w http.ResponseWriter, r *http.Request) (commitment if err != nil { err = fmt.Errorf("failed to decode commitment from key %v (commitment mode %v): %w", key, meta.Mode, err) svr.WriteBadRequest(w, err) - return meta, err + return commitments.CommitmentMeta{}, MetaError{ + Err: err, + Meta: meta, + } } } @@ -215,14 +236,20 @@ func (svr *Server) HandlePut(w http.ResponseWriter, r *http.Request) (commitment if err != nil { err = fmt.Errorf("put request failed with commitment %v (commitment mode %v): %w", comm, meta.Mode, err) svr.WriteInternalError(w, err) - return meta, err + return commitments.CommitmentMeta{}, MetaError{ + Err: err, + Meta: meta, + } } responseCommit, err := commitments.EncodeCommitment(commitment, meta.Mode) if err != nil { err = fmt.Errorf("failed to encode commitment %v (commitment mode %v): %w", commitment, meta.Mode, err) svr.WriteInternalError(w, err) - return meta, err + return commitments.CommitmentMeta{}, MetaError{ + Err: err, + Meta: meta, + } } svr.log.Info(fmt.Sprintf("write commitment: %x\n", comm)) diff --git a/server/server_test.go b/server/server_test.go index 863375a4..6a2a3e17 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -85,7 +85,7 @@ func TestGetHandler(t *testing.T) { expectedCode: http.StatusInternalServerError, expectedBody: "", expectError: true, - expectedCommitmentMeta: commitments.CommitmentMeta{Mode: commitments.OptimismGeneric, CertVersion: 0}, + expectedCommitmentMeta: commitments.CommitmentMeta{}, }, { name: "Success - OP Keccak256", @@ -107,7 +107,7 @@ func TestGetHandler(t *testing.T) { expectedCode: http.StatusInternalServerError, expectedBody: "", expectError: true, - expectedCommitmentMeta: commitments.CommitmentMeta{Mode: commitments.OptimismAltDA, CertVersion: 0}, + expectedCommitmentMeta: commitments.CommitmentMeta{}, }, { name: "Success - OP Alt-DA", @@ -217,11 +217,10 @@ func TestPutHandler(t *testing.T) { mockBehavior: func() { mockRouter.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, fmt.Errorf("internal error")) }, - expectedCode: http.StatusInternalServerError, - expectedBody: "", - expectError: true, - // certification version is the third byte of the body, in this case it's "m" - expectedCommitmentMeta: commitments.CommitmentMeta{Mode: commitments.OptimismAltDA, CertVersion: 0}, + expectedCode: http.StatusInternalServerError, + expectedBody: "", + expectError: true, + expectedCommitmentMeta: commitments.CommitmentMeta{}, }, { name: "Success OP Mode Alt-DA",