1
0
Fork 0
mirror of https://github.com/Eggbertx/gochan.git synced 2025-09-13 09:26:23 -07:00

Avoid deferring calls to Close() if it may return an error

This commit is contained in:
Eggbertx 2024-02-06 12:30:18 -08:00
parent dfb3225bfd
commit d892e77b3b
11 changed files with 62 additions and 69 deletions

View file

@ -32,8 +32,25 @@ for the threads and board pages`
var (
versionStr string
dbVersionStr string
migrator common.DBMigrator
)
func close() int {
returnVal := 0
var err error
if migrator != nil {
if err = migrator.Close(); err != nil {
returnVal = 1
log.Println("Error closing migrator:", err.Error())
}
}
if err = gcsql.Close(); err != nil {
returnVal = 1
log.Println("Error closing SQL connection:", err.Error())
}
return returnVal
}
func main() {
var options common.MigrationOptions
var dirAction string
@ -69,7 +86,6 @@ func main() {
}
log.Printf(banner, versionStr)
var migrator common.DBMigrator
switch options.ChanType {
case "gcupdate":
migrator = &gcupdate.GCDatabaseUpdater{}
@ -98,10 +114,10 @@ func main() {
if err = gcsql.CheckAndInitializeDatabase(systemCritical.DBtype); err != nil {
log.Fatalf("Failed to initialize the database: %s", err.Error())
}
defer gcsql.Close()
}
if err = migrator.Init(&options); err != nil {
close()
log.Fatalf("Unable to initialize %s migrator: %s\n",
options.ChanType, err.Error())
return
@ -110,15 +126,17 @@ func main() {
var migrated bool
if migrated, err = migrator.MigrateDB(); err != nil {
close()
log.Fatalln("Error migrating database:", err.Error())
}
if migrated {
log.Println("Database is already migrated")
os.Exit(0)
return
}
if updateDB {
log.Println("Database schema updated successfully")
} else {
log.Println(migrateCompleteTxt)
}
os.Exit(close())
}

View file

@ -25,14 +25,16 @@ var (
versionStr string
)
func close() {
gcutil.LogInfo().Msg("Cleaning up")
gcsql.Close()
geoip.Close()
gcplugin.ClosePlugins()
gcutil.CloseLog()
}
func main() {
defer func() {
gcutil.LogInfo().Msg("Cleaning up")
gcsql.Close()
geoip.Close()
gcplugin.ClosePlugins()
gcutil.CloseLog()
}()
defer close()
fmt.Printf("Starting gochan v%s\n", versionStr)
config.InitConfig(versionStr)
@ -43,6 +45,7 @@ func main() {
err := gcutil.InitLogs(systemCritical.LogDir, true, uid, gid)
if err != nil {
fmt.Println("Error opening logs:", err.Error())
close()
os.Exit(1)
}
@ -53,6 +56,7 @@ func main() {
}
if err = gcplugin.LoadPlugins(systemCritical.Plugins); err != nil {
close()
gcutil.LogFatal().Err(err).Msg("failed loading plugins")
}
@ -63,6 +67,7 @@ func main() {
systemCritical.DBhost, systemCritical.DBtype, systemCritical.DBname,
systemCritical.DBusername, systemCritical.DBpassword, systemCritical.DBprefix,
); err != nil {
close()
fmt.Println("Failed to connect to the database:", err.Error())
gcutil.LogFatal().Err(err).Msg("Failed to connect to the database")
}
@ -72,6 +77,7 @@ func main() {
Msg("Connected to database")
if err = gcsql.CheckAndInitializeDatabase(systemCritical.DBtype); err != nil {
close()
gcutil.LogFatal().Err(err).Msg("Failed to initialize the database")
}
events.TriggerEvent("db-initialized")
@ -79,18 +85,21 @@ func main() {
serverutil.InitMinifier()
siteCfg := config.GetSiteConfig()
if err = geoip.SetupGeoIP(siteCfg.GeoIPType, siteCfg.GeoIPOptions); err != nil {
close()
gcutil.LogFatal().Err(err).Msg("Unable to initialize GeoIP")
}
posting.InitCaptcha()
if err = gctemplates.InitTemplates(); err != nil {
fmt.Println("Failed initializing templates:", err.Error())
close()
gcutil.LogFatal().Err(err).Send()
}
for _, board := range gcsql.AllBoards {
if _, err = board.DeleteOldThreads(); err != nil {
fmt.Printf("Error deleting old threads for board /%s/: %s\n", board.Dir, err)
close()
gcutil.LogFatal().Err(err).Caller().
Str("board", board.Dir).
Msg("Failed deleting old threads")
@ -102,6 +111,7 @@ func main() {
posting.InitPosting()
if err = gcutil.InitLogs(systemCritical.LogDir, systemCritical.Verbose, uid, gid); err != nil {
fmt.Println("Error opening logs:", err.Error())
close()
os.Exit(1)
}
go initServer()

View file

@ -166,7 +166,6 @@ func BuildBoardPages(board *gcsql.Board) error {
Msg("Failed getting board page")
return fmt.Errorf("failed opening /%s/board.html: %s", board.Dir, err.Error())
}
defer boardPageFile.Close()
if err = config.TakeOwnershipOfFile(boardPageFile); err != nil {
errEv.Err(err).Caller().
@ -192,7 +191,7 @@ func BuildBoardPages(board *gcsql.Board) error {
Caller().Msg("Failed building board")
return fmt.Errorf("failed building /%s/: %s", board.Dir, err.Error())
}
return nil
return boardPageFile.Close()
}
// Create the archive pages.
@ -208,7 +207,6 @@ func BuildBoardPages(board *gcsql.Board) error {
Msg("Failed opening catalog.json")
return fmt.Errorf("failed opening /%s/catalog.json: %s", board.Dir, err.Error())
}
defer catalogJSONFile.Close()
if err = config.TakeOwnershipOfFile(catalogJSONFile); err != nil {
errEv.Err(err).Caller().
@ -227,7 +225,6 @@ func BuildBoardPages(board *gcsql.Board) error {
Msg("Failed getting board page")
continue
}
defer currentPageFile.Close()
if err = config.TakeOwnershipOfFile(currentPageFile); err != nil {
errEv.Err(err).Caller().
@ -261,10 +258,13 @@ func BuildBoardPages(board *gcsql.Board) error {
data["nextPage"] = catalog.currentPage + 1
}
if err = serverutil.MinifyTemplate(gctemplates.BoardPage, data, currentPageFile, "text/html"); err != nil {
errEv.Err(err).
Caller().Send()
errEv.Err(err).Caller().Send()
return fmt.Errorf("failed building /%s/ boardpage: %s", board.Dir, err.Error())
}
if err = currentPageFile.Close(); err != nil {
errEv.Err(err).Caller().Send()
return fmt.Errorf("failed building /%s/ board page", board.Dir)
}
// Collect up threads for this page.
page := catalogPage{}
@ -283,7 +283,7 @@ func BuildBoardPages(board *gcsql.Board) error {
Caller().Msg("Failed writing catalog.json")
return fmt.Errorf("failed writing /%s/catalog.json: %s", board.Dir, err.Error())
}
return nil
return catalogJSONFile.Close()
}
// BuildBoards builds the specified board IDs, or all boards if no arguments are passed
@ -551,7 +551,6 @@ func BuildBoardListJSON() error {
errEv.Err(err).Caller().Send()
return errors.New("unable to open boards.json for writing: " + err.Error())
}
defer boardListFile.Close()
if err = config.TakeOwnershipOfFile(boardListFile); err != nil {
errEv.Err(err).Caller().Send()
@ -587,5 +586,5 @@ func BuildBoardListJSON() error {
errEv.Err(err).Caller().Send()
return errors.New("Failed writing boards.json file: " + err.Error())
}
return nil
return boardListFile.Close()
}

View file

@ -97,7 +97,6 @@ func BuildFrontPage() error {
errEv.Err(err).Caller().Send()
return errors.New("Failed opening front page for writing: " + err.Error())
}
defer frontFile.Close()
if err = config.TakeOwnershipOfFile(frontFile); err != nil {
errEv.Err(err).Caller().Send()
@ -121,7 +120,7 @@ func BuildFrontPage() error {
errEv.Err(err).Caller().Send()
return errors.New("Failed executing front page template: " + err.Error())
}
return nil
return frontFile.Close()
}
// BuildPageHeader is a convenience function for automatically generating the top part
@ -166,7 +165,6 @@ func BuildJS() error {
errEv.Err(err).Caller().Send()
return fmt.Errorf("error opening consts.js for writing: %s", err.Error())
}
defer constsJSFile.Close()
if err = config.TakeOwnershipOfFile(constsJSFile); err != nil {
errEv.Err(err).Caller().Send()
@ -182,5 +180,5 @@ func BuildJS() error {
errEv.Err(err).Caller().Send()
return fmt.Errorf("error building consts.js: %s", err.Error())
}
return nil
return constsJSFile.Close()
}

View file

@ -98,7 +98,6 @@ func BuildCatalog(boardID int) error {
errEv.Err(err).Caller().Send()
return fmt.Errorf("failed opening /%s/catalog.html: %s", board.Dir, err.Error())
}
defer catalogFile.Close()
if err = config.TakeOwnershipOfFile(catalogFile); err != nil {
errEv.Err(err).Caller().Send()
@ -122,5 +121,5 @@ func BuildCatalog(boardID int) error {
errEv.Err(err).Caller().Send()
return fmt.Errorf("failed building catalog for /%s/: %s", board.Dir, err.Error())
}
return nil
return catalogFile.Close()
}

View file

@ -88,7 +88,7 @@ func BuildThreadPages(op *gcsql.Post) error {
errEv.Err(err).Caller().Send()
return fmt.Errorf("unable to open /%s/res/%d.html: %s", board.Dir, op.ID, err.Error())
}
defer threadPageFile.Close()
if err = config.TakeOwnershipOfFile(threadPageFile); err != nil {
errEv.Err(err).Caller().Send()
return fmt.Errorf("unable to set file permissions for /%s/res/%d.html: %s", board.Dir, op.ID, err.Error())
@ -111,6 +111,10 @@ func BuildThreadPages(op *gcsql.Post) error {
errEv.Err(err).Caller().Send()
return fmt.Errorf("failed building /%s/res/%d threadpage: %s", board.Dir, posts[0].ID, err.Error())
}
if err = threadPageFile.Close(); err != nil {
errEv.Err(err).Caller().Send()
return errors.New("failed closing thread page file")
}
// Put together the thread JSON
threadJSONFile, err := os.OpenFile(
@ -120,7 +124,6 @@ func BuildThreadPages(op *gcsql.Post) error {
errEv.Err(err).Caller().Send()
return fmt.Errorf("failed opening /%s/res/%d.json: %s", board.Dir, posts[0].ID, err.Error())
}
defer threadJSONFile.Close()
if err = config.TakeOwnershipOfFile(threadJSONFile); err != nil {
errEv.Err(err).Caller().Send()
@ -140,5 +143,5 @@ func BuildThreadPages(op *gcsql.Post) error {
Caller().Send()
return fmt.Errorf("failed writing /%s/res/%d.json: %s", board.Dir, posts[0].ID, err.Error())
}
return nil
return threadJSONFile.Close()
}

View file

@ -112,14 +112,13 @@ func InitConfig(versionStr string) {
os.Exit(1)
}
cfgFile, err := os.Open(cfgPath)
cfgBytes, err := os.ReadFile(cfgPath)
if err != nil {
fmt.Printf("Error reading %s: %s\n", cfgPath, err.Error())
os.Exit(1)
}
defer cfgFile.Close()
if err = json.NewDecoder(cfgFile).Decode(cfg); err != nil {
if err = json.Unmarshal(cfgBytes, cfg); err != nil {
fmt.Printf("Error parsing %s: %s", cfgPath, err.Error())
os.Exit(1)
}
@ -186,25 +185,6 @@ func InitConfig(versionStr string) {
cfg.WebRoot += "/"
}
/* if !cfg.validGeoIPType() {
gcutil.LogFatal().Caller().
Str("GeoIPDBType", cfg.GeoIPDBType).
Msg("Invalid GeoIPDBType value, valid values are '', 'none', 'legacy', or 'geoip2'")
}
if cfg.GeoIPDBType != "" && cfg.GeoIPDBlocation != "" {
if _, err = os.Stat(cfg.GeoIPDBlocation); os.IsNotExist(err) {
gcutil.LogWarning().
Str("location", cfg.GeoIPDBlocation).
Msg("Unable to load GeoIP database location set in gochan.json, disabling GeoIP")
cfg.EnableGeoIP = false
} else if err != nil {
gcutil.LogFatal().Err(err).
Str("location", cfg.GeoIPDBlocation).
Msg("Unable to load GeoIP database location set in gochan.json")
}
} */
_, zoneOffset := time.Now().Zone()
cfg.TimeZone = zoneOffset / 60 / 60

View file

@ -253,9 +253,7 @@ var funcMap = template.FuncMap{
"boardPagePath": func(board *gcsql.Board, page int) string {
return config.WebPath(board.Dir, strconv.Itoa(page)+".html")
},
"webPath": func(part ...string) string {
return config.WebPath(part...)
},
"webPath": config.WebPath,
"webPathDir": func(part ...string) string {
dir := config.WebPath(part...)
if len(dir) > 0 && dir[len(dir)-1] != '/' {

View file

@ -127,11 +127,7 @@ func InitLogs(logDir string, verbose bool, uid int, gid int) (err error) {
if err = initAccessLog(path.Join(logDir, "gochan_access.log")); err != nil {
return err
}
if err = accessFile.Chown(uid, gid); err != nil {
return err
}
return nil
return accessFile.Chown(uid, gid)
}
func Logger() *zerolog.Logger {

View file

@ -5,7 +5,6 @@ import (
"database/sql"
"errors"
"fmt"
"io"
"net/http"
"os"
"path"
@ -809,20 +808,14 @@ func registerAdminPages() {
Callback: func(writer http.ResponseWriter, request *http.Request, staff *gcsql.Staff, wantsJSON bool, infoEv *zerolog.Event,
errEv *zerolog.Event) (output interface{}, err error) {
logPath := path.Join(config.GetSystemCriticalConfig().LogDir, "gochan.log")
logFile, err := os.Open(logPath)
logBytes, err := os.ReadFile(logPath)
if err != nil {
errEv.Err(err).Caller().Send()
return "", errors.New("unable to open log file")
}
defer logFile.Close()
ba, err := io.ReadAll(logFile)
if err != nil {
errEv.Err(err).Caller().Send()
return "", err
}
buf := bytes.NewBufferString("")
err = serverutil.MinifyTemplate(gctemplates.ManageViewLog, map[string]interface{}{
"logText": string(ba),
"logText": string(logBytes),
}, buf, "text/html")
return buf.String(), err
},

View file

@ -44,12 +44,11 @@ func numImageFrames(imgPath string) (int, error) {
if err != nil {
return 0, err
}
defer fi.Close()
g, err := gif.DecodeAll(fi)
if err != nil {
return 0, err
}
return len(g.Image), nil
return len(g.Image), fi.Close()
}
func processImage(upload *gcsql.Upload, post *gcsql.Post, board string, filePath string, thumbPath string, catalogThumbPath string, infoEv *zerolog.Event, accessEv *zerolog.Event, errEv *zerolog.Event) error {