mirror of
https://github.com/pocketbase/pocketbase.git
synced 2026-10-22 14:04:05 +02:00
added non-zero exit status support for returned command errors
This commit is contained in:
1 parent
fd25a8ae32
commit
200c19b26f
2 files changed
+25
-36
No files matched your search
+4
-1
@@ -1,4 +1,7 @@
|
|||||||
## v0.39.11 (WIP)
|
## v0.40.0 (WIP)
|
||||||
|
|
||||||
|
- Propagate console command errors and recovered panics to `app.Start()` so that the program can exit with non-zero code while still ensuring that `app.OnTerminate` hook (responsible for the app graceful shutdown handling) was triggered.
|
||||||
|
_⚠️ Note that this could be a slight breaking change in case you are chaining PocketBase commands and relied on the previous `0` exit status for `Command.RunE` returned errors._
|
||||||
|
|
||||||
- Fixed "API preview" examples ([#7782](https://github.com/pocketbase/pocketbase/issues/7782)).
|
- Fixed "API preview" examples ([#7782](https://github.com/pocketbase/pocketbase/issues/7782)).
|
||||||
|
|
||||||
|
|||||||
+21
-35
@@ -1,6 +1,7 @@
|
|||||||
package pocketbase
|
package pocketbase
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
@@ -9,7 +10,6 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/fatih/color"
|
|
||||||
"github.com/pocketbase/pocketbase/cmd"
|
"github.com/pocketbase/pocketbase/cmd"
|
||||||
"github.com/pocketbase/pocketbase/core"
|
"github.com/pocketbase/pocketbase/core"
|
||||||
"github.com/pocketbase/pocketbase/tools/hook"
|
"github.com/pocketbase/pocketbase/tools/hook"
|
||||||
@@ -117,8 +117,9 @@ func NewWithConfig(config Config) *PocketBase {
|
|||||||
hideStartBanner: config.HideStartBanner,
|
hideStartBanner: config.HideStartBanner,
|
||||||
}
|
}
|
||||||
|
|
||||||
// replace with a colored stderr writer
|
// don't write command errors to the stderr because the error is
|
||||||
pb.RootCmd.SetErr(newErrWriter())
|
// propagated back to the app.Start() and could result in duplication
|
||||||
|
pb.RootCmd.SetErr(&nopWrite{})
|
||||||
|
|
||||||
// parse base flags
|
// parse base flags
|
||||||
// (errors are ignored, since the full flags parsing happens on Execute())
|
// (errors are ignored, since the full flags parsing happens on Execute())
|
||||||
@@ -183,26 +184,25 @@ func (pb *PocketBase) Execute() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
done := make(chan bool, 1)
|
execCh := make(chan error, 1)
|
||||||
|
sigCh := make(chan os.Signal, 1)
|
||||||
|
|
||||||
// listen for interrupt signal to gracefully shutdown the application
|
// listen for interrupt signal to gracefully shutdown the application
|
||||||
go func() {
|
signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM)
|
||||||
sigch := make(chan os.Signal, 1)
|
|
||||||
signal.Notify(sigch, os.Interrupt, syscall.SIGTERM)
|
|
||||||
<-sigch
|
|
||||||
|
|
||||||
done <- true
|
|
||||||
}()
|
|
||||||
|
|
||||||
// execute the root command
|
// execute the root command
|
||||||
go func() {
|
go func() {
|
||||||
// note: leave to the commands to decide whether to print their error
|
execCh <- routine.SafeWrap(pb.RootCmd.Execute)()
|
||||||
pb.RootCmd.Execute()
|
|
||||||
|
|
||||||
done <- true
|
|
||||||
}()
|
}()
|
||||||
|
|
||||||
<-done
|
// wait for either an OS signal or the command to complete
|
||||||
|
var execErr error
|
||||||
|
select {
|
||||||
|
case <-sigCh:
|
||||||
|
case execErr = <-execCh:
|
||||||
|
}
|
||||||
|
|
||||||
|
signal.Stop(sigCh)
|
||||||
|
|
||||||
// trigger cleanups
|
// trigger cleanups
|
||||||
//
|
//
|
||||||
@@ -210,7 +210,7 @@ func (pb *PocketBase) Execute() error {
|
|||||||
event := new(core.TerminateEvent)
|
event := new(core.TerminateEvent)
|
||||||
event.App = pb
|
event.App = pb
|
||||||
return pb.OnTerminate().Trigger(event, func(e *core.TerminateEvent) error {
|
return pb.OnTerminate().Trigger(event, func(e *core.TerminateEvent) error {
|
||||||
return e.App.ResetBootstrapState()
|
return errors.Join(e.App.ResetBootstrapState(), execErr)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -308,24 +308,10 @@ func inspectRuntime() (baseDir string, withGoRun bool) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// newErrWriter returns a red colored stderr writter.
|
var _ io.Writer = (*nopWrite)(nil)
|
||||||
func newErrWriter() *coloredWriter {
|
|
||||||
return &coloredWriter{
|
|
||||||
w: os.Stderr,
|
|
||||||
c: color.New(color.FgRed),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// coloredWriter is a small wrapper struct to construct a [color.Color] writter.
|
type nopWrite struct{}
|
||||||
type coloredWriter struct {
|
|
||||||
w io.Writer
|
|
||||||
c *color.Color
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write writes the p bytes using the colored writer.
|
func (w *nopWrite) Write(p []byte) (n int, err error) {
|
||||||
func (colored *coloredWriter) Write(p []byte) (n int, err error) {
|
return
|
||||||
colored.c.SetWriter(colored.w)
|
|
||||||
defer colored.c.UnsetWriter(colored.w)
|
|
||||||
|
|
||||||
return colored.c.Print(string(p))
|
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user