Commit d7543094 authored by Robert Griesemer's avatar Robert Griesemer

godoc: report Status 404 if a pkg or file is not found

Fixes #1005.

R=rsc, r
CC=golang-dev
https://golang.org/cl/1935041
parent 9714c220
...@@ -218,6 +218,7 @@ func codewalkFileprint(c *http.Conn, r *http.Request, f string) { ...@@ -218,6 +218,7 @@ func codewalkFileprint(c *http.Conn, r *http.Request, f string) {
abspath := absolutePath(f, *goroot) abspath := absolutePath(f, *goroot)
data, err := ioutil.ReadFile(abspath) data, err := ioutil.ReadFile(abspath)
if err != nil { if err != nil {
log.Stderr(err)
serveError(c, r, f, err) serveError(c, r, f, err)
return return
} }
......
...@@ -1186,7 +1186,6 @@ type PageInfoMode uint ...@@ -1186,7 +1186,6 @@ type PageInfoMode uint
const ( const (
exportsOnly PageInfoMode = 1 << iota // only keep exported stuff exportsOnly PageInfoMode = 1 << iota // only keep exported stuff
genDoc // generate documentation genDoc // generate documentation
tryMode // don't log errors
) )
...@@ -1197,6 +1196,7 @@ type PageInfo struct { ...@@ -1197,6 +1196,7 @@ type PageInfo struct {
PDoc *doc.PackageDoc // nil if no single package documentation PDoc *doc.PackageDoc // nil if no single package documentation
Dirs *DirList // nil if no directory information Dirs *DirList // nil if no directory information
IsPkg bool // false if this is not documenting a real package IsPkg bool // false if this is not documenting a real package
Err os.Error // directory read error or nil
} }
...@@ -1210,10 +1210,10 @@ type httpHandler struct { ...@@ -1210,10 +1210,10 @@ type httpHandler struct {
// getPageInfo returns the PageInfo for a package directory abspath. If the // getPageInfo returns the PageInfo for a package directory abspath. If the
// parameter genAST is set, an AST containing only the package exports is // parameter genAST is set, an AST containing only the package exports is
// computed (PageInfo.PAst), otherwise package documentation (PageInfo.Doc) // computed (PageInfo.PAst), otherwise package documentation (PageInfo.Doc)
// is extracted from the AST. If the parameter try is set, no errors are // is extracted from the AST. If there is no corresponding package in the
// logged if getPageInfo fails. If there is no corresponding package in the // directory, PageInfo.PAst and PageInfo.PDoc are nil. If there are no sub-
// directory, PageInfo.PDoc and PageInfo.PExp are nil. If there are no sub- // directories, PageInfo.Dirs is nil. If a directory read error occured,
// directories, PageInfo.Dirs is nil. // PageInfo.Err is set to the respective error but the error is not logged.
// //
func (h *httpHandler) getPageInfo(abspath, relpath, pkgname string, mode PageInfoMode) PageInfo { func (h *httpHandler) getPageInfo(abspath, relpath, pkgname string, mode PageInfoMode) PageInfo {
// filter function to select the desired .go files // filter function to select the desired .go files
...@@ -1225,9 +1225,10 @@ func (h *httpHandler) getPageInfo(abspath, relpath, pkgname string, mode PageInf ...@@ -1225,9 +1225,10 @@ func (h *httpHandler) getPageInfo(abspath, relpath, pkgname string, mode PageInf
// get package ASTs // get package ASTs
pkgs, err := parser.ParseDir(abspath, filter, parser.ParseComments) pkgs, err := parser.ParseDir(abspath, filter, parser.ParseComments)
if err != nil && mode&tryMode != 0 { if err != nil && pkgs == nil {
// TODO: errors should be shown instead of an empty directory // only report directory read errors, ignore parse errors
log.Stderrf("parser.parseDir: %s", err) // (may be able to extract partial package information)
return PageInfo{Dirname: abspath, Err: err}
} }
// select package // select package
...@@ -1314,7 +1315,7 @@ func (h *httpHandler) getPageInfo(abspath, relpath, pkgname string, mode PageInf ...@@ -1314,7 +1315,7 @@ func (h *httpHandler) getPageInfo(abspath, relpath, pkgname string, mode PageInf
dir = newDirectory(abspath, 1) dir = newDirectory(abspath, 1)
} }
return PageInfo{abspath, plist, past, pdoc, dir.listing(true), h.isPkg} return PageInfo{abspath, plist, past, pdoc, dir.listing(true), h.isPkg, nil}
} }
...@@ -1330,6 +1331,11 @@ func (h *httpHandler) ServeHTTP(c *http.Conn, r *http.Request) { ...@@ -1330,6 +1331,11 @@ func (h *httpHandler) ServeHTTP(c *http.Conn, r *http.Request) {
mode |= genDoc mode |= genDoc
} }
info := h.getPageInfo(abspath, relpath, r.FormValue("p"), mode) info := h.getPageInfo(abspath, relpath, r.FormValue("p"), mode)
if info.Err != nil {
log.Stderr(info.Err)
serveError(c, r, relpath, info.Err)
return
}
if r.FormValue("f") == "text" { if r.FormValue("f") == "text" {
contents := applyTemplate(packageText, "packageText", info) contents := applyTemplate(packageText, "packageText", info)
......
...@@ -66,6 +66,7 @@ var ( ...@@ -66,6 +66,7 @@ var (
func serveError(c *http.Conn, r *http.Request, relpath string, err os.Error) { func serveError(c *http.Conn, r *http.Request, relpath string, err os.Error) {
contents := applyTemplate(errorHTML, "errorHTML", err) // err may contain an absolute path! contents := applyTemplate(errorHTML, "errorHTML", err) // err may contain an absolute path!
c.WriteHeader(http.StatusNotFound)
servePage(c, "File "+relpath, "", "", contents) servePage(c, "File "+relpath, "", "", contents)
} }
...@@ -333,15 +334,18 @@ func main() { ...@@ -333,15 +334,18 @@ func main() {
} }
// TODO(gri): Provide a mechanism (flag?) to select a package // TODO(gri): Provide a mechanism (flag?) to select a package
// if there are multiple packages in a directory. // if there are multiple packages in a directory.
info := pkgHandler.getPageInfo(abspath, relpath, "", mode|tryMode) info := pkgHandler.getPageInfo(abspath, relpath, "", mode)
if info.PAst == nil && info.PDoc == nil && info.Dirs == nil { if info.Err != nil || info.PAst == nil && info.PDoc == nil && info.Dirs == nil {
// try again, this time assume it's a command // try again, this time assume it's a command
if len(path) > 0 && path[0] != '/' { if len(path) > 0 && path[0] != '/' {
abspath = absolutePath(path, cmdHandler.fsRoot) abspath = absolutePath(path, cmdHandler.fsRoot)
} }
info = cmdHandler.getPageInfo(abspath, relpath, "", mode) info = cmdHandler.getPageInfo(abspath, relpath, "", mode)
} }
if info.Err != nil {
log.Exitf("%v", info.Err)
}
// If we have more than one argument, use the remaining arguments for filtering // If we have more than one argument, use the remaining arguments for filtering
if flag.NArg() > 1 { if flag.NArg() > 1 {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment