feat: recover from panic
This commit is contained in:
		
							parent
							
								
									ab41926fc0
								
							
						
					
					
						commit
						4639e84ad5
					
				|  | @ -146,8 +146,18 @@ func mainImpl() (err error) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func main() { | func main() { | ||||||
| 	if err := mainImpl(); err != nil { | 	var err error | ||||||
| 		slog.Error("main exit", "error", err) | 	exitCode := 0 | ||||||
| 		os.Exit(1) | 	defer func() { | ||||||
| 	} | 		if r := recover(); r != nil { | ||||||
|  | 			slog.Error("panic recovered", "panic", r) | ||||||
|  | 			exitCode = 2 | ||||||
|  | 		} | ||||||
|  | 		if err != nil { | ||||||
|  | 			slog.Error("main exit", "error", err) | ||||||
|  | 			exitCode = 1 | ||||||
|  | 		} | ||||||
|  | 		os.Exit(exitCode) | ||||||
|  | 	}() | ||||||
|  | 	err = mainImpl() | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -22,7 +22,10 @@ func generateStages(confStages []conf.ConfStage, groups []string) ( | ||||||
| ) { | ) { | ||||||
| 	stages := []stage.Stage{} | 	stages := []stage.Stage{} | ||||||
| 	existNames := map[string]bool{} | 	existNames := map[string]bool{} | ||||||
| 	for _, s := range confStages { | 	for i, s := range confStages { | ||||||
|  | 		if s.Name == "" { | ||||||
|  | 			s.Name = fmt.Sprintf("stage-%d", i) | ||||||
|  | 		} | ||||||
| 		if s.Group != "" { | 		if s.Group != "" { | ||||||
| 			var ok bool | 			var ok bool | ||||||
| 			for _, group := range groups { | 			for _, group := range groups { | ||||||
|  |  | ||||||
|  | @ -16,140 +16,164 @@ func Run(stages []Stage) ( | ||||||
| 	var tmpParserResults []ParserResult | 	var tmpParserResults []ParserResult | ||||||
| 	slog.Info("stage run start") | 	slog.Info("stage run start") | ||||||
| 	for _, stage := range stages { | 	for _, stage := range stages { | ||||||
| 		slog.Info("stage start", "name", stage.Name) | 		func() { | ||||||
| 		slog.Info( | 			defer func() { | ||||||
| 			"executor run start", | 				if r := recover(); r != nil { | ||||||
| 			"stageName", stage.Name, | 					slog.Error( | ||||||
| 			"name", stage.Executor.Name, | 						"stage panic recovered", | ||||||
| 		) | 						"stageName", stage.Name, | ||||||
| 		slog.Debug( | 						"panic", r, | ||||||
| 			"executor run start", | 					) | ||||||
| 			"stageName", stage.Name, | 					stageResults = append(stageResults, StageResult{ | ||||||
| 			"name", stage.Executor.Name, | 						Name: stage.Name, | ||||||
| 			"cmds", stage.Executor.Cmds, | 						Results: []ParserResult{ | ||||||
| 		) | 							{ | ||||||
| 		executor, ok := executorMap[stage.Executor.Name] | 								Score: 0, | ||||||
| 		if !ok { | 								Comment: "JOJ3 internal error. " + | ||||||
| 			slog.Error( | 									"Please contact the administrator.\n", | ||||||
| 				"executor not found", | 							}, | ||||||
|  | 						}, | ||||||
|  | 						ForceQuit: true, | ||||||
|  | 					}) | ||||||
|  | 					forceQuitStageName = stage.Name | ||||||
|  | 					err = fmt.Errorf("panic in stage %s: %v", stage.Name, r) | ||||||
|  | 				} | ||||||
|  | 			}() | ||||||
|  | 			slog.Info("stage start", "name", stage.Name) | ||||||
|  | 			slog.Info( | ||||||
|  | 				"executor run start", | ||||||
| 				"stageName", stage.Name, | 				"stageName", stage.Name, | ||||||
| 				"name", stage.Executor.Name, | 				"name", stage.Executor.Name, | ||||||
| 			) | 			) | ||||||
| 			err = fmt.Errorf("executor not found: %s", stage.Executor.Name) | 			slog.Debug( | ||||||
| 			return stageResults, forceQuitStageName, err | 				"executor run start", | ||||||
| 		} |  | ||||||
| 		executorResults, err = executor.Run(stage.Executor.Cmds) |  | ||||||
| 		if err != nil { |  | ||||||
| 			slog.Error( |  | ||||||
| 				"executor run error", |  | ||||||
| 				"stageName", stage.Name, | 				"stageName", stage.Name, | ||||||
| 				"name", stage.Executor.Name, | 				"name", stage.Executor.Name, | ||||||
| 				"error", err, | 				"cmds", stage.Executor.Cmds, | ||||||
| 			) | 			) | ||||||
| 			return stageResults, forceQuitStageName, err | 			executor, ok := executorMap[stage.Executor.Name] | ||||||
| 		} | 			if !ok { | ||||||
| 		for i, executorResult := range executorResults { | 				slog.Error( | ||||||
|  | 					"executor not found", | ||||||
|  | 					"stageName", stage.Name, | ||||||
|  | 					"name", stage.Executor.Name, | ||||||
|  | 				) | ||||||
|  | 				err = fmt.Errorf("executor not found: %s", stage.Executor.Name) | ||||||
|  | 				return | ||||||
|  | 			} | ||||||
|  | 			executorResults, err = executor.Run(stage.Executor.Cmds) | ||||||
|  | 			if err != nil { | ||||||
|  | 				slog.Error( | ||||||
|  | 					"executor run error", | ||||||
|  | 					"stageName", stage.Name, | ||||||
|  | 					"name", stage.Executor.Name, | ||||||
|  | 					"error", err, | ||||||
|  | 				) | ||||||
|  | 				return | ||||||
|  | 			} | ||||||
|  | 			for i, executorResult := range executorResults { | ||||||
|  | 				slog.Debug( | ||||||
|  | 					"executor run done", | ||||||
|  | 					"stageName", stage.Name, | ||||||
|  | 					"case", i, | ||||||
|  | 					"name", stage.Executor.Name, | ||||||
|  | 					"result", executorResult, | ||||||
|  | 				) | ||||||
|  | 			} | ||||||
| 			slog.Debug( | 			slog.Debug( | ||||||
| 				"executor run done", | 				"executor run done", | ||||||
| 				"stageName", stage.Name, | 				"stageName", stage.Name, | ||||||
| 				"case", i, |  | ||||||
| 				"name", stage.Executor.Name, | 				"name", stage.Executor.Name, | ||||||
| 				"result", executorResult, | 				"summary", SummarizeExecutorResults(executorResults), | ||||||
| 			) | 			) | ||||||
| 		} | 			parserResults = []ParserResult{} | ||||||
| 		slog.Debug( | 			stageDetail := StageDetail{ | ||||||
| 			"executor run done", | 				Name:        stage.Name, | ||||||
| 			"stageName", stage.Name, | 				CaseDetails: make([]CaseDetail, len(executorResults)), | ||||||
| 			"name", stage.Executor.Name, | 			} | ||||||
| 			"summary", SummarizeExecutorResults(executorResults), | 			parserScoresMap := map[string][]int{} | ||||||
| 		) | 			for _, parser := range stage.Parsers { | ||||||
| 		parserResults = []ParserResult{} | 				parserScoresMap[parser.Name] = make([]int, len(executorResults)) | ||||||
| 		stageDetail := StageDetail{ | 			} | ||||||
| 			Name:        stage.Name, | 			for _, stageParser := range stage.Parsers { | ||||||
| 			CaseDetails: make([]CaseDetail, len(executorResults)), | 				slog.Info( | ||||||
| 		} | 					"parser run start", | ||||||
| 		parserScoresMap := map[string][]int{} |  | ||||||
| 		for _, parser := range stage.Parsers { |  | ||||||
| 			parserScoresMap[parser.Name] = make([]int, len(executorResults)) |  | ||||||
| 		} |  | ||||||
| 		for _, stageParser := range stage.Parsers { |  | ||||||
| 			slog.Info( |  | ||||||
| 				"parser run start", |  | ||||||
| 				"stageName", stage.Name, |  | ||||||
| 				"name", stageParser.Name, |  | ||||||
| 			) |  | ||||||
| 			slog.Debug( |  | ||||||
| 				"parser run start", |  | ||||||
| 				"stageName", stage.Name, |  | ||||||
| 				"name", stageParser.Name, |  | ||||||
| 				"conf", stageParser.Conf, |  | ||||||
| 			) |  | ||||||
| 			parser, ok := parserMap[stageParser.Name] |  | ||||||
| 			if !ok { |  | ||||||
| 				slog.Error( |  | ||||||
| 					"parser not found", |  | ||||||
| 					"stageName", stage.Name, | 					"stageName", stage.Name, | ||||||
| 					"name", stageParser.Name, | 					"name", stageParser.Name, | ||||||
| 				) | 				) | ||||||
| 				err = fmt.Errorf("parser not found: %s", stageParser.Name) | 				slog.Debug( | ||||||
| 				return stageResults, forceQuitStageName, err | 					"parser run start", | ||||||
| 			} |  | ||||||
| 			var parserForceQuit bool |  | ||||||
| 			tmpParserResults, parserForceQuit, err = parser.Run( |  | ||||||
| 				executorResults, stageParser.Conf) |  | ||||||
| 			if err != nil { |  | ||||||
| 				slog.Error( |  | ||||||
| 					"parser run error", |  | ||||||
| 					"stageName", stage.Name, | 					"stageName", stage.Name, | ||||||
| 					"name", stageParser.Name, | 					"name", stageParser.Name, | ||||||
| 					"error", err, | 					"conf", stageParser.Conf, | ||||||
| 				) | 				) | ||||||
| 				forceQuitStageName = stage.Name | 				parser, ok := parserMap[stageParser.Name] | ||||||
| 				break | 				if !ok { | ||||||
| 			} | 					slog.Error( | ||||||
| 			for i, parserResult := range tmpParserResults { | 						"parser not found", | ||||||
| 				parserScoresMap[stageParser.Name][i] += parserResult.Score | 						"stageName", stage.Name, | ||||||
| 			} | 						"name", stageParser.Name, | ||||||
| 			if parserForceQuit { | 					) | ||||||
| 				slog.Error( | 					err = fmt.Errorf("parser not found: %s", stageParser.Name) | ||||||
| 					"parser force quit", | 					return | ||||||
|  | 				} | ||||||
|  | 				var parserForceQuit bool | ||||||
|  | 				tmpParserResults, parserForceQuit, err = parser.Run( | ||||||
|  | 					executorResults, stageParser.Conf) | ||||||
|  | 				if err != nil { | ||||||
|  | 					slog.Error( | ||||||
|  | 						"parser run error", | ||||||
|  | 						"stageName", stage.Name, | ||||||
|  | 						"name", stageParser.Name, | ||||||
|  | 						"error", err, | ||||||
|  | 					) | ||||||
|  | 					forceQuitStageName = stage.Name | ||||||
|  | 					break | ||||||
|  | 				} | ||||||
|  | 				for i, parserResult := range tmpParserResults { | ||||||
|  | 					parserScoresMap[stageParser.Name][i] += parserResult.Score | ||||||
|  | 				} | ||||||
|  | 				if parserForceQuit { | ||||||
|  | 					slog.Error( | ||||||
|  | 						"parser force quit", | ||||||
|  | 						"stageName", stage.Name, | ||||||
|  | 						"name", stageParser.Name, | ||||||
|  | 					) | ||||||
|  | 					forceQuitStageName = stage.Name | ||||||
|  | 				} | ||||||
|  | 				slog.Debug( | ||||||
|  | 					"parser run done", | ||||||
| 					"stageName", stage.Name, | 					"stageName", stage.Name, | ||||||
| 					"name", stageParser.Name, | 					"name", stageParser.Name, | ||||||
|  | 					"results", tmpParserResults, | ||||||
| 				) | 				) | ||||||
| 				forceQuitStageName = stage.Name | 				if len(parserResults) == 0 { | ||||||
| 			} | 					parserResults = tmpParserResults | ||||||
| 			slog.Debug( | 				} else { | ||||||
| 				"parser run done", | 					for i := range len(parserResults) { | ||||||
| 				"stageName", stage.Name, | 						parserResults[i].Score += tmpParserResults[i].Score | ||||||
| 				"name", stageParser.Name, | 						parserResults[i].Comment += tmpParserResults[i].Comment | ||||||
| 				"results", tmpParserResults, | 					} | ||||||
| 			) |  | ||||||
| 			if len(parserResults) == 0 { |  | ||||||
| 				parserResults = tmpParserResults |  | ||||||
| 			} else { |  | ||||||
| 				for i := range len(parserResults) { |  | ||||||
| 					parserResults[i].Score += tmpParserResults[i].Score |  | ||||||
| 					parserResults[i].Comment += tmpParserResults[i].Comment |  | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 			for i := range executorResults { | ||||||
| 		for i := range executorResults { | 				caseDetail := CaseDetail{ | ||||||
| 			caseDetail := CaseDetail{ | 					Index:          i, | ||||||
| 				Index:          i, | 					ExecutorResult: executorResults[i], | ||||||
| 				ExecutorResult: executorResults[i], | 					ParserScores:   make(map[string]int), | ||||||
| 				ParserScores:   make(map[string]int), | 				} | ||||||
|  | 				for name, scores := range parserScoresMap { | ||||||
|  | 					caseDetail.ParserScores[name] = scores[i] | ||||||
|  | 				} | ||||||
|  | 				stageDetail.CaseDetails[i] = caseDetail | ||||||
| 			} | 			} | ||||||
| 			for name, scores := range parserScoresMap { | 			stageResults = append(stageResults, StageResult{ | ||||||
| 				caseDetail.ParserScores[name] = scores[i] | 				Name:      stage.Name, | ||||||
| 			} | 				Results:   parserResults, | ||||||
| 			stageDetail.CaseDetails[i] = caseDetail | 				ForceQuit: forceQuitStageName != "", | ||||||
| 		} | 			}) | ||||||
| 		stageResults = append(stageResults, StageResult{ | 			slog.Debug("stage done", "name", stage.Name, "stageDetail", stageDetail) | ||||||
| 			Name:      stage.Name, | 		}() | ||||||
| 			Results:   parserResults, |  | ||||||
| 			ForceQuit: forceQuitStageName != "", |  | ||||||
| 		}) |  | ||||||
| 		slog.Debug("stage done", "name", stage.Name, "stageDetail", stageDetail) |  | ||||||
| 		if forceQuitStageName != "" { | 		if forceQuitStageName != "" { | ||||||
| 			break | 			break | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user