updated jsvm panic handling when HooksWatch is set
This commit is contained in:
		
							parent
							
								
									0a4fdc17a5
								
							
						
					
					
						commit
						6da94aef8d
					
				| 
						 | 
					@ -188,6 +188,10 @@ func routerBinds(app core.App, loader *goja.Runtime, executors *vmsPool) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func wrapHandler(executors *vmsPool, handler goja.Value) (echo.HandlerFunc, error) {
 | 
					func wrapHandler(executors *vmsPool, handler goja.Value) (echo.HandlerFunc, error) {
 | 
				
			||||||
 | 
						if handler == nil {
 | 
				
			||||||
 | 
							return nil, errors.New("handler must be non-nil")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch h := handler.Export().(type) {
 | 
						switch h := handler.Export().(type) {
 | 
				
			||||||
	case echo.HandlerFunc:
 | 
						case echo.HandlerFunc:
 | 
				
			||||||
		// "native" handler - no need to wrap
 | 
							// "native" handler - no need to wrap
 | 
				
			||||||
| 
						 | 
					@ -222,6 +226,10 @@ func wrapMiddlewares(executors *vmsPool, rawMiddlewares ...goja.Value) ([]echo.M
 | 
				
			||||||
	wrappedMiddlewares := make([]echo.MiddlewareFunc, len(rawMiddlewares))
 | 
						wrappedMiddlewares := make([]echo.MiddlewareFunc, len(rawMiddlewares))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for i, m := range rawMiddlewares {
 | 
						for i, m := range rawMiddlewares {
 | 
				
			||||||
 | 
							if m == nil {
 | 
				
			||||||
 | 
								return nil, errors.New("middleware func must be non-nil")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		switch v := m.Export().(type) {
 | 
							switch v := m.Export().(type) {
 | 
				
			||||||
		case echo.MiddlewareFunc:
 | 
							case echo.MiddlewareFunc:
 | 
				
			||||||
			// "native" middleware - no need to wrap
 | 
								// "native" middleware - no need to wrap
 | 
				
			||||||
| 
						 | 
					@ -271,7 +279,7 @@ func baseBinds(vm *goja.Runtime) {
 | 
				
			||||||
	vm.Set("DynamicModel", func(call goja.ConstructorCall) *goja.Object {
 | 
						vm.Set("DynamicModel", func(call goja.ConstructorCall) *goja.Object {
 | 
				
			||||||
		shape, ok := call.Argument(0).Export().(map[string]any)
 | 
							shape, ok := call.Argument(0).Export().(map[string]any)
 | 
				
			||||||
		if !ok || len(shape) == 0 {
 | 
							if !ok || len(shape) == 0 {
 | 
				
			||||||
			panic("missing shape data")
 | 
								panic("[DynamicModel] missing shape data")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		instance := newDynamicModel(shape)
 | 
							instance := newDynamicModel(shape)
 | 
				
			||||||
| 
						 | 
					@ -364,7 +372,7 @@ func baseBinds(vm *goja.Runtime) {
 | 
				
			||||||
	vm.Set("Dao", func(call goja.ConstructorCall) *goja.Object {
 | 
						vm.Set("Dao", func(call goja.ConstructorCall) *goja.Object {
 | 
				
			||||||
		concurrentDB, _ := call.Argument(0).Export().(dbx.Builder)
 | 
							concurrentDB, _ := call.Argument(0).Export().(dbx.Builder)
 | 
				
			||||||
		if concurrentDB == nil {
 | 
							if concurrentDB == nil {
 | 
				
			||||||
			panic("missing required Dao(concurrentDB, [nonconcurrentDB]) argument")
 | 
								panic("[Dao] missing required Dao(concurrentDB, [nonconcurrentDB]) argument")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		nonConcurrentDB, _ := call.Argument(1).Export().(dbx.Builder)
 | 
							nonConcurrentDB, _ := call.Argument(1).Export().(dbx.Builder)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,9 +34,6 @@ import (
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	hooksExtension      = ".pb.js"
 | 
					 | 
				
			||||||
	migrationsExtension = ".js"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	typesFileName = "types.d.ts"
 | 
						typesFileName = "types.d.ts"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -53,6 +50,13 @@ type Config struct {
 | 
				
			||||||
	// If not set it fallbacks to a relative "pb_data/../pb_hooks" directory.
 | 
						// If not set it fallbacks to a relative "pb_data/../pb_hooks" directory.
 | 
				
			||||||
	HooksDir string
 | 
						HooksDir string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// HooksFilesPattern specifies a regular expression pattern that
 | 
				
			||||||
 | 
						// identify which file to load by the hook vm(s).
 | 
				
			||||||
 | 
						//
 | 
				
			||||||
 | 
						// If not set it fallbacks to `^.*(\.pb\.js|\.pb\.ts)$`, aka. any
 | 
				
			||||||
 | 
						// HookdsDir file ending in ".pb.js" or ".pb.ts" (the last one is to enforce IDE linters).
 | 
				
			||||||
 | 
						HooksFilesPattern string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// HooksPoolSize specifies how many goja.Runtime instances to prewarm
 | 
						// HooksPoolSize specifies how many goja.Runtime instances to prewarm
 | 
				
			||||||
	// and keep for the JS app hooks gorotines execution.
 | 
						// and keep for the JS app hooks gorotines execution.
 | 
				
			||||||
	//
 | 
						//
 | 
				
			||||||
| 
						 | 
					@ -65,6 +69,10 @@ type Config struct {
 | 
				
			||||||
	// If not set it fallbacks to a relative "pb_data/../pb_migrations" directory.
 | 
						// If not set it fallbacks to a relative "pb_data/../pb_migrations" directory.
 | 
				
			||||||
	MigrationsDir string
 | 
						MigrationsDir string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// If not set it fallbacks to `^.*(\.js|\.ts)$`, aka. any MigrationDir file
 | 
				
			||||||
 | 
						// ending in ".js" or ".ts" (the last one is to enforce IDE linters).
 | 
				
			||||||
 | 
						MigrationsFilesPattern string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// TypesDir specifies the directory where to store the embedded
 | 
						// TypesDir specifies the directory where to store the embedded
 | 
				
			||||||
	// TypeScript declarations file.
 | 
						// TypeScript declarations file.
 | 
				
			||||||
	//
 | 
						//
 | 
				
			||||||
| 
						 | 
					@ -96,6 +104,14 @@ func Register(app core.App, config Config) error {
 | 
				
			||||||
		p.config.MigrationsDir = filepath.Join(app.DataDir(), "../pb_migrations")
 | 
							p.config.MigrationsDir = filepath.Join(app.DataDir(), "../pb_migrations")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if p.config.HooksFilesPattern == "" {
 | 
				
			||||||
 | 
							p.config.HooksFilesPattern = `^.*(\.pb\.js|\.pb\.ts)$`
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if p.config.MigrationsFilesPattern == "" {
 | 
				
			||||||
 | 
							p.config.MigrationsFilesPattern = `^.*(\.js|\.ts)$`
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if p.config.TypesDir == "" {
 | 
						if p.config.TypesDir == "" {
 | 
				
			||||||
		p.config.TypesDir = app.DataDir()
 | 
							p.config.TypesDir = app.DataDir()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -129,7 +145,7 @@ type plugin struct {
 | 
				
			||||||
// registerMigrations registers the JS migrations loader.
 | 
					// registerMigrations registers the JS migrations loader.
 | 
				
			||||||
func (p *plugin) registerMigrations() error {
 | 
					func (p *plugin) registerMigrations() error {
 | 
				
			||||||
	// fetch all js migrations sorted by their filename
 | 
						// fetch all js migrations sorted by their filename
 | 
				
			||||||
	files, err := filesContent(p.config.MigrationsDir, `^.*`+regexp.QuoteMeta(migrationsExtension)+`$`)
 | 
						files, err := filesContent(p.config.MigrationsDir, p.config.MigrationsFilesPattern)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -168,7 +184,7 @@ func (p *plugin) registerMigrations() error {
 | 
				
			||||||
// registerHooks registers the JS app hooks loader.
 | 
					// registerHooks registers the JS app hooks loader.
 | 
				
			||||||
func (p *plugin) registerHooks() error {
 | 
					func (p *plugin) registerHooks() error {
 | 
				
			||||||
	// fetch all js hooks sorted by their filename
 | 
						// fetch all js hooks sorted by their filename
 | 
				
			||||||
	files, err := filesContent(p.config.HooksDir, `^.*`+regexp.QuoteMeta(hooksExtension)+`$`)
 | 
						files, err := filesContent(p.config.HooksDir, p.config.HooksFilesPattern)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -250,14 +266,24 @@ func (p *plugin) registerHooks() error {
 | 
				
			||||||
	routerBinds(p.app, loader, executors)
 | 
						routerBinds(p.app, loader, executors)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for file, content := range files {
 | 
						for file, content := range files {
 | 
				
			||||||
 | 
							func() {
 | 
				
			||||||
 | 
								defer func() {
 | 
				
			||||||
 | 
									if err := recover(); err != nil {
 | 
				
			||||||
 | 
										fmtErr := fmt.Errorf("Failed to execute %s:\n - %v", file, err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										if p.config.HooksWatch {
 | 
				
			||||||
 | 
											color.Red("%v", fmtErr)
 | 
				
			||||||
 | 
										} else {
 | 
				
			||||||
 | 
											panic(fmtErr)
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			_, err := loader.RunString(string(content))
 | 
								_, err := loader.RunString(string(content))
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
			if p.config.HooksWatch {
 | 
					 | 
				
			||||||
				color.Red("Failed to execute %s: %v", file, err)
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				panic(err)
 | 
									panic(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue