const (
exportsOnly PageInfoMode = 1 << iota // only keep exported stuff
genDoc // generate documentation
- tryMode // don't log errors
)
PDoc *doc.PackageDoc // nil if no single package documentation
Dirs *DirList // nil if no directory information
IsPkg bool // false if this is not documenting a real package
+ Err os.Error // directory read error or nil
}
// getPageInfo returns the PageInfo for a package directory abspath. If the
// parameter genAST is set, an AST containing only the package exports is
// computed (PageInfo.PAst), otherwise package documentation (PageInfo.Doc)
-// is extracted from the AST. If the parameter try is set, no errors are
-// logged if getPageInfo fails. If there is no corresponding package in the
-// directory, PageInfo.PDoc and PageInfo.PExp are nil. If there are no sub-
-// directories, PageInfo.Dirs is nil.
+// is extracted from the AST. If there is no corresponding package in the
+// directory, PageInfo.PAst and PageInfo.PDoc are nil. If there are no sub-
+// directories, PageInfo.Dirs is nil. If a directory read error occured,
+// 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 {
// filter function to select the desired .go files
// get package ASTs
pkgs, err := parser.ParseDir(abspath, filter, parser.ParseComments)
- if err != nil && mode&tryMode != 0 {
- // TODO: errors should be shown instead of an empty directory
- log.Stderrf("parser.parseDir: %s", err)
+ if err != nil && pkgs == nil {
+ // only report directory read errors, ignore parse errors
+ // (may be able to extract partial package information)
+ return PageInfo{Dirname: abspath, Err: err}
}
// select package
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}
}
mode |= genDoc
}
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" {
contents := applyTemplate(packageText, "packageText", info)
func serveError(c *http.Conn, r *http.Request, relpath string, err os.Error) {
contents := applyTemplate(errorHTML, "errorHTML", err) // err may contain an absolute path!
+ c.WriteHeader(http.StatusNotFound)
servePage(c, "File "+relpath, "", "", contents)
}
}
// TODO(gri): Provide a mechanism (flag?) to select a package
// 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
if len(path) > 0 && path[0] != '/' {
abspath = absolutePath(path, cmdHandler.fsRoot)
}
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 flag.NArg() > 1 {