Monorepo for Tangled

appview/{xrpcclient,repo}: show 404 for missing files and paths instead of 503 #1

open opened by murex.tngl.sh targeting master from fix/404-instead-of-503

Add ErrXrpcNotFound and treat 404s with resource-not-found tags (FileNotFound, PathNotFound, RefNotFound, etc.) as ErrXrpcNotFound. Treat other 404s as ErrXrpcUnsupported. In blob, tree, and log handlers, return the 404 page for ErrXrpcNotFound instead of the 503 page.

Signed-off-by: Nupur Agrawal nupur202000@gmail.com

Labels

None yet.

assignee

None yet.

Participants 1
AT URI
at://did:plc:owyua2lvxbs55wyhs22dqu2s/sh.tangled.repo.pull/3mgijogdlkz22
+61 -6
Diff #0
+7 -1
appview/repo/blob.go
··· 2 2 3 3 import ( 4 4 "encoding/base64" 5 + "errors" 5 6 "fmt" 6 7 "io" 7 8 "net/http" ··· 62 63 resp, err := tangled.RepoBlob(r.Context(), xrpcc, filePath, false, ref, repo) 63 64 if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { 64 65 l.Error("failed to call XRPC repo.blob", "err", xrpcerr) 65 - rp.pages.Error503(w) 66 + if errors.Is(xrpcerr, xrpcclient.ErrXrpcNotFound) { 67 + w.WriteHeader(http.StatusNotFound) 68 + rp.pages.Error404(w) 69 + } else { 70 + rp.pages.Error503(w) 71 + } 66 72 return 67 73 } 68 74
+25 -4
appview/repo/log.go
··· 2 2 3 3 import ( 4 4 "encoding/json" 5 + "errors" 5 6 "fmt" 6 7 "net/http" 7 8 "net/url" ··· 61 62 xrpcBytes, err := tangled.RepoLog(r.Context(), xrpcc, cursor, limit, "", ref, repo) 62 63 if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { 63 64 l.Error("failed to call XRPC repo.log", "err", xrpcerr) 64 - rp.pages.Error503(w) 65 + if errors.Is(xrpcerr, xrpcclient.ErrXrpcNotFound) { 66 + w.WriteHeader(http.StatusNotFound) 67 + rp.pages.Error404(w) 68 + } else { 69 + rp.pages.Error503(w) 70 + } 65 71 return 66 72 } 67 73 ··· 75 81 tagBytes, err := tangled.RepoTags(r.Context(), xrpcc, "", 0, repo) 76 82 if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { 77 83 l.Error("failed to call XRPC repo.tags", "err", xrpcerr) 78 - rp.pages.Error503(w) 84 + if errors.Is(xrpcerr, xrpcclient.ErrXrpcNotFound) { 85 + w.WriteHeader(http.StatusNotFound) 86 + rp.pages.Error404(w) 87 + } else { 88 + rp.pages.Error503(w) 89 + } 79 90 return 80 91 } 81 92 ··· 96 107 branchBytes, err := tangled.RepoBranches(r.Context(), xrpcc, "", 0, repo) 97 108 if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { 98 109 l.Error("failed to call XRPC repo.branches", "err", xrpcerr) 99 - rp.pages.Error503(w) 110 + if errors.Is(xrpcerr, xrpcclient.ErrXrpcNotFound) { 111 + w.WriteHeader(http.StatusNotFound) 112 + rp.pages.Error404(w) 113 + } else { 114 + rp.pages.Error503(w) 115 + } 100 116 return 101 117 } 102 118 ··· 176 192 xrpcBytes, err := tangled.RepoDiff(r.Context(), xrpcc, ref, repo) 177 193 if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { 178 194 l.Error("failed to call XRPC repo.diff", "err", xrpcerr) 179 - rp.pages.Error503(w) 195 + if errors.Is(xrpcerr, xrpcclient.ErrXrpcNotFound) { 196 + w.WriteHeader(http.StatusNotFound) 197 + rp.pages.Error404(w) 198 + } else { 199 + rp.pages.Error503(w) 200 + } 180 201 return 181 202 } 182 203
+7 -1
appview/repo/tree.go
··· 1 1 package repo 2 2 3 3 import ( 4 + "errors" 4 5 "fmt" 5 6 "net/http" 6 7 "net/url" ··· 45 46 xrpcResp, err := tangled.RepoTree(r.Context(), xrpcc, treePath, ref, repo) 46 47 if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { 47 48 l.Error("failed to call XRPC repo.tree", "err", xrpcerr) 48 - rp.pages.Error503(w) 49 + if errors.Is(xrpcerr, xrpcclient.ErrXrpcNotFound) { 50 + w.WriteHeader(http.StatusNotFound) 51 + rp.pages.Error404(w) 52 + } else { 53 + rp.pages.Error503(w) 54 + } 49 55 return 50 56 } 51 57 // Convert XRPC response to internal types.RepoTreeResponse
+22
appview/xrpcclient/xrpc.go
··· 3 3 import ( 4 4 "errors" 5 5 "net/http" 6 + "strings" 6 7 7 8 indigoxrpc "github.com/bluesky-social/indigo/xrpc" 8 9 ) 9 10 10 11 var ( 11 12 ErrXrpcUnsupported = errors.New("xrpc not supported on this knot") 13 + ErrXrpcNotFound = errors.New("resource not found") 12 14 ErrXrpcUnauthorized = errors.New("unauthorized xrpc request") 13 15 ErrXrpcFailed = errors.New("xrpc request failed") 14 16 ErrXrpcInvalid = errors.New("invalid xrpc request") 15 17 ) 16 18 19 + // resourceNotFoundTags are XRPC error tags that indicate a missing resource 20 + // (file, path, ref, etc.), as opposed to an unsupported feature (spindle, knot, etc.) 21 + var resourceNotFoundTags = []string{ 22 + "FileNotFound", "PathNotFound", "RefNotFound", 23 + "BranchNotFound", "TagNotFound", "RevisionNotFound", "RepoNotFound", 24 + } 25 + 17 26 // produces a more manageable error 18 27 func HandleXrpcErr(err error) error { 19 28 if err == nil { ··· 27 36 28 37 switch xrpcerr.StatusCode { 29 38 case http.StatusNotFound: 39 + if isResourceNotFound(xrpcerr) { 40 + return ErrXrpcNotFound 41 + } 30 42 return ErrXrpcUnsupported 31 43 case http.StatusUnauthorized: 32 44 return ErrXrpcUnauthorized ··· 34 46 return ErrXrpcFailed 35 47 } 36 48 } 49 + 50 + func isResourceNotFound(xrpcerr *indigoxrpc.Error) bool { 51 + errStr := xrpcerr.Error() 52 + for _, tag := range resourceNotFoundTags { 53 + if strings.Contains(errStr, tag) { 54 + return true 55 + } 56 + } 57 + return false 58 + }

History

1 round 0 comments
sign up or login to add to the discussion
murex.tngl.sh submitted #0
1 commit
expand
appview/{xrpcclient,repo}: show 404 for missing files and paths instead of 503
no conflicts, ready to merge
expand 0 comments