From c200ef6900612305d08b9b09888ef87b4eea9eb6 Mon Sep 17 00:00:00 2001 From: debugtalk Date: Fri, 21 Oct 2022 20:35:02 +0800 Subject: [PATCH] change: add exit code --- hrp/boomer.go | 9 +++--- hrp/build.go | 29 ++++++++++++------ hrp/cmd/boom.go | 12 ++++---- hrp/cmd/curl.go | 14 +++++---- hrp/cmd/scaffold.go | 3 +- hrp/internal/builtin/utils.go | 18 ++++++----- hrp/internal/code/code.go | 56 +++++++++++++++++++++++++++-------- hrp/internal/myexec/cmd.go | 3 +- hrp/loader.go | 2 +- hrp/parser.go | 19 +++++++----- hrp/plugin.go | 5 +++- hrp/runner_test.go | 5 ++-- hrp/step_request.go | 5 ++-- hrp/testcase.go | 28 ++++++++++++------ 14 files changed, 137 insertions(+), 71 deletions(-) diff --git a/hrp/boomer.go b/hrp/boomer.go index c3db1e76..4e3ecef5 100644 --- a/hrp/boomer.go +++ b/hrp/boomer.go @@ -14,6 +14,7 @@ import ( "golang.org/x/net/context" "github.com/httprunner/httprunner/v4/hrp/internal/builtin" + "github.com/httprunner/httprunner/v4/hrp/internal/code" "github.com/httprunner/httprunner/v4/hrp/internal/json" "github.com/httprunner/httprunner/v4/hrp/internal/sdk" "github.com/httprunner/httprunner/v4/hrp/pkg/boomer" @@ -121,7 +122,7 @@ func (b *HRPBoomer) ConvertTestCasesToBoomerTasks(testcases ...ITestCase) (taskS testCases, err := LoadTestCases(testcases...) if err != nil { log.Error().Err(err).Msg("failed to load testcases") - os.Exit(1) + os.Exit(code.GetErrorCode(err)) } for _, testcase := range testCases { @@ -139,7 +140,7 @@ func (b *HRPBoomer) ParseTestCases(testCases []*TestCase) []*TCase { caseRunner, err := b.hrpRunner.NewCaseRunner(tc) if err != nil { log.Error().Err(err).Msg("failed to create runner") - os.Exit(1) + os.Exit(code.GetErrorCode(err)) } caseRunner.parsedConfig.Parameters = caseRunner.parametersIterator.outParameters() parsedTestCases = append(parsedTestCases, &TCase{ @@ -155,7 +156,7 @@ func (b *HRPBoomer) TestCasesToBytes(testcases ...ITestCase) []byte { testCases, err := LoadTestCases(testcases...) if err != nil { log.Error().Err(err).Msg("failed to load testcases") - os.Exit(1) + os.Exit(code.GetErrorCode(err)) } tcs := b.ParseTestCases(testCases) testCasesBytes, err := json.Marshal(tcs) @@ -318,7 +319,7 @@ func (b *HRPBoomer) convertBoomerTask(testcase *TestCase, rendezvousList []*Rend caseRunner, err := b.hrpRunner.NewCaseRunner(testcase) if err != nil { log.Error().Err(err).Msg("failed to create runner") - os.Exit(1) + os.Exit(code.GetErrorCode(err)) } if caseRunner.parser.plugin != nil { b.pluginsMutex.Lock() diff --git a/hrp/build.go b/hrp/build.go index bf950fde..491bdb8f 100644 --- a/hrp/build.go +++ b/hrp/build.go @@ -15,6 +15,7 @@ import ( "github.com/rs/zerolog/log" "github.com/httprunner/httprunner/v4/hrp/internal/builtin" + "github.com/httprunner/httprunner/v4/hrp/internal/code" "github.com/httprunner/httprunner/v4/hrp/internal/myexec" "github.com/httprunner/httprunner/v4/hrp/internal/version" ) @@ -175,11 +176,11 @@ func buildGo(path string, output string) error { content, err := os.ReadFile(path) if err != nil { log.Error().Err(err).Msg("failed to read file") - return errors.Wrap(err, "read file failed") + return errors.Wrap(code.LoadFileError, err.Error()) } functionNames, err := regexGoFunctionName.findAllFunctionNames(string(content)) if err != nil { - return err + return errors.Wrap(code.InvalidPluginFile, err.Error()) } templateContent := &pluginTemplate{ @@ -187,7 +188,11 @@ func buildGo(path string, output string) error { Version: version.VERSION, FunctionNames: functionNames, } - return templateContent.generateGo(output) + err = templateContent.generateGo(output) + if err != nil { + return errors.Wrap(code.BuildGoPluginFailed, err.Error()) + } + return nil } // buildPy completes funppy information in debugtalk.py @@ -196,17 +201,18 @@ func buildPy(path string, output string) error { // check the syntax of debugtalk.py err := myexec.ExecPython3Command("py_compile", path) if err != nil { - return errors.Wrap(err, "python plugin syntax invalid") + return errors.Wrap(code.InvalidPluginFile, + fmt.Sprintf("python plugin syntax invalid: %s", err.Error())) } content, err := os.ReadFile(path) if err != nil { log.Error().Err(err).Msg("failed to read file") - return errors.Wrap(err, "read file failed") + return errors.Wrap(code.LoadFileError, err.Error()) } functionNames, err := regexPyFunctionName.findAllFunctionNames(string(content)) if err != nil { - return err + return errors.Wrap(code.InvalidPluginFile, err.Error()) } templateContent := &pluginTemplate{ @@ -214,7 +220,11 @@ func buildPy(path string, output string) error { Version: version.VERSION, FunctionNames: functionNames, } - return templateContent.generatePy(output) + err = templateContent.generatePy(output) + if err != nil { + return errors.Wrap(code.BuildPyPluginFailed, err.Error()) + } + return nil } func BuildPlugin(path string, output string) (err error) { @@ -225,11 +235,12 @@ func BuildPlugin(path string, output string) (err error) { case ".go": err = buildGo(path, output) default: - return errors.New("type error, expected .py or .go") + return errors.Wrap(code.UnsupportedFileExtension, + "type error, expected .py or .go") } if err != nil { log.Error().Err(err).Str("path", path).Msg("build plugin failed") - os.Exit(1) + return err } return nil } diff --git a/hrp/cmd/boom.go b/hrp/cmd/boom.go index d5f853f4..08cff659 100644 --- a/hrp/cmd/boom.go +++ b/hrp/cmd/boom.go @@ -1,7 +1,6 @@ package cmd import ( - "os" "strings" "time" @@ -30,7 +29,7 @@ var boomCmd = &cobra.Command{ } setLogLevel(logLevel) }, - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { var paths []hrp.ITestCase for _, arg := range args { path := hrp.TestCasePath(arg) @@ -42,7 +41,7 @@ var boomCmd = &cobra.Command{ err := builtin.LoadFile(boomArgs.profile, &boomArgs.Profile) if err != nil { log.Error().Err(err).Msg("failed to load profile") - os.Exit(1) + return err } } @@ -89,6 +88,7 @@ var boomCmd = &cobra.Command{ hrpBoomer.InitBoomer() hrpBoomer.Run(paths...) } + return nil }, } @@ -141,13 +141,13 @@ func init() { boomCmd.Flags().IntVar(&boomArgs.expectWorkersMaxWait, "expect-workers-max-wait", 120, "How many workers master should expect to connect before starting the test (only when --autostart is used") } -func makeHRPBoomer() *hrp.HRPBoomer { +func makeHRPBoomer() (*hrp.HRPBoomer, error) { // if set profile, the priority is higher than the other commands if boomArgs.profile != "" { err := builtin.LoadFile(boomArgs.profile, &boomArgs) if err != nil { log.Error().Err(err).Msg("failed to load profile") - os.Exit(1) + return nil, err } } hrpBoomer := hrp.NewStandaloneBoomer(boomArgs.SpawnCount, boomArgs.SpawnRate) @@ -157,5 +157,5 @@ func makeHRPBoomer() *hrp.HRPBoomer { hrpBoomer.SetProfile(&boomArgs.Profile) hrpBoomer.EnableGracefulQuit(context.Background()) hrpBoomer.InitBoomer() - return hrpBoomer + return hrpBoomer, nil } diff --git a/hrp/cmd/curl.go b/hrp/cmd/curl.go index 02c18a7f..2fdda0cc 100644 --- a/hrp/cmd/curl.go +++ b/hrp/cmd/curl.go @@ -21,11 +21,9 @@ var runCurlCmd = &cobra.Command{ PreRun: func(cmd *cobra.Command, args []string) { setLogLevel(logLevel) }, - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { runner := makeHRPRunner() - if runner.Run(makeCurlTestCase(args)) != nil { - os.Exit(1) - } + return runner.Run(makeCurlTestCase(args)) }, } @@ -41,9 +39,13 @@ var boomCurlCmd = &cobra.Command{ } setLogLevel(logLevel) }, - Run: func(cmd *cobra.Command, args []string) { - boomer := makeHRPBoomer() + RunE: func(cmd *cobra.Command, args []string) error { + boomer, err := makeHRPBoomer() + if err != nil { + return err + } boomer.Run(makeCurlTestCase(args)) + return nil }, } diff --git a/hrp/cmd/scaffold.go b/hrp/cmd/scaffold.go index 86830725..b127b0ab 100644 --- a/hrp/cmd/scaffold.go +++ b/hrp/cmd/scaffold.go @@ -2,7 +2,6 @@ package cmd import ( "errors" - "os" "github.com/rs/zerolog/log" "github.com/spf13/cobra" @@ -37,7 +36,7 @@ var scaffoldCmd = &cobra.Command{ err := scaffold.CreateScaffold(args[0], pluginType, venv, force) if err != nil { log.Error().Err(err).Msg("create scaffold project failed") - os.Exit(1) + return err } log.Info().Str("projectName", args[0]).Msg("create scaffold success") return nil diff --git a/hrp/internal/builtin/utils.go b/hrp/internal/builtin/utils.go index c79939c8..bfa9c323 100644 --- a/hrp/internal/builtin/utils.go +++ b/hrp/internal/builtin/utils.go @@ -22,6 +22,7 @@ import ( "github.com/rs/zerolog/log" "gopkg.in/yaml.v3" + "github.com/httprunner/httprunner/v4/hrp/internal/code" "github.com/httprunner/httprunner/v4/hrp/internal/json" ) @@ -235,8 +236,6 @@ func InterfaceType(raw interface{}) string { return reflect.TypeOf(raw).String() } -var ErrUnsupportedFileExt = fmt.Errorf("unsupported file extension") - // LoadFile loads file content with file extension and assigns to structObj func LoadFile(path string, structObj interface{}) (err error) { log.Info().Str("path", path).Msg("load file") @@ -252,12 +251,15 @@ func LoadFile(path string, structObj interface{}) (err error) { decoder := json.NewDecoder(bytes.NewReader(file)) decoder.UseNumber() err = decoder.Decode(structObj) + err = errors.Wrap(code.LoadJSONError, err.Error()) case ".yaml", ".yml": err = yaml.Unmarshal(file, structObj) + err = errors.Wrap(code.LoadYAMLError, err.Error()) case ".env": err = parseEnvContent(file, structObj) + err = errors.Wrap(code.LoadEnvError, err.Error()) default: - err = ErrUnsupportedFileExt + err = code.UnsupportedFileExtension } return err } @@ -297,14 +299,14 @@ func loadFromCSV(path string) []map[string]interface{} { file, err := ReadFile(path) if err != nil { log.Error().Err(err).Msg("read csv file failed") - os.Exit(1) + os.Exit(code.GetErrorCode(err)) } r := csv.NewReader(strings.NewReader(string(file))) content, err := r.ReadAll() if err != nil { log.Error().Err(err).Msg("parse csv file failed") - os.Exit(1) + os.Exit(code.GetErrorCode(err)) } firstLine := content[0] // parameter names var result []map[string]interface{} @@ -323,7 +325,7 @@ func loadMessage(path string) []byte { file, err := ReadFile(path) if err != nil { log.Error().Err(err).Msg("read message file failed") - os.Exit(1) + os.Exit(code.GetErrorCode(err)) } return file } @@ -333,13 +335,13 @@ func ReadFile(path string) ([]byte, error) { path, err = filepath.Abs(path) if err != nil { log.Error().Err(err).Str("path", path).Msg("convert absolute path failed") - return nil, err + return nil, errors.Wrap(code.LoadFileError, err.Error()) } file, err := os.ReadFile(path) if err != nil { log.Error().Err(err).Msg("read file failed") - return nil, err + return nil, errors.Wrap(code.LoadFileError, err.Error()) } return file, nil } diff --git a/hrp/internal/code/code.go b/hrp/internal/code/code.go index e47b729a..9bf517b1 100644 --- a/hrp/internal/code/code.go +++ b/hrp/internal/code/code.go @@ -12,24 +12,40 @@ const ( ) // environment: [2, 10) +var ( + InvalidPython3Venv = errors.New("prepare python3 venv failed") // 9 +) // loader: [10, 20) var ( - LoadError = errors.New("load error") // 10 - LoadJSONError = errors.New("load json error") // 11 - LoadYAMLError = errors.New("load yaml error") // 12 + LoadFileError = errors.New("load file error") // 10 + LoadJSONError = errors.New("load json error") // 11 + LoadYAMLError = errors.New("load yaml error") // 12 + LoadEnvError = errors.New("load .env error") // 13 + LoadCSVError = errors.New("load csv error") // 14 + InvalidCaseFormat = errors.New("invalid case format") // 15 + UnsupportedFileExtension = errors.New("unsupported file extension") // 16 + ReferencedFileNotFound = errors.New("referenced file not found") // 17 + InvalidPluginFile = errors.New("invalid plugin file") // 18 ) // parser: [20, 30) var ( ParseError = errors.New("parse error") // 20 - ParseStringError = errors.New("parse string failed") // 21 - ParseVariablesError = errors.New("parse variables failed") // 22 - ParseConfigError = errors.New("parse config error") // 25 + VariableNotFound = errors.New("variable not found") // 21 + ParseFunctionError = errors.New("parse function failed") // 22 + CallFunctionError = errors.New("call function failed") // 23 + ParseVariablesError = errors.New("parse variables failed") // 24 ) // runner: [30, 40) +var ( + InitPluginFailed = errors.New("init plugin failed") // 31 + BuildGoPluginFailed = errors.New("build go plugin failed") // 32 + BuildPyPluginFailed = errors.New("build py plugin failed") // 33 +) + // summary: [40, 50) // ios device related: [50, 60) @@ -67,16 +83,31 @@ var ( // CV related: [90, 100) var errorsMap = map[error]int{ + // environment + InvalidPython3Venv: 9, + // loader - LoadError: 10, - LoadJSONError: 11, - LoadYAMLError: 12, + LoadFileError: 10, + LoadJSONError: 11, + LoadYAMLError: 12, + LoadEnvError: 13, + LoadCSVError: 14, + InvalidCaseFormat: 15, + UnsupportedFileExtension: 16, + ReferencedFileNotFound: 17, + InvalidPluginFile: 18, // parser ParseError: 20, - ParseStringError: 21, - ParseVariablesError: 22, - ParseConfigError: 25, + VariableNotFound: 21, + ParseFunctionError: 22, + CallFunctionError: 23, + ParseVariablesError: 24, + + // runner + InitPluginFailed: 31, + BuildGoPluginFailed: 32, + BuildPyPluginFailed: 33, // ios related IOSDeviceConnectionError: 50, @@ -105,7 +136,6 @@ var errorsMap = map[error]int{ func GetErrorCode(err error) (exitCode int) { if err == nil { - log.Info().Int("code", Success).Msg("hrp exit") return Success } diff --git a/hrp/internal/myexec/cmd.go b/hrp/internal/myexec/cmd.go index 3876008e..b92e312e 100644 --- a/hrp/internal/myexec/cmd.go +++ b/hrp/internal/myexec/cmd.go @@ -10,6 +10,7 @@ import ( "github.com/pkg/errors" "github.com/rs/zerolog/log" + "github.com/httprunner/httprunner/v4/hrp/internal/code" "github.com/httprunner/httprunner/v4/hrp/internal/env" ) @@ -39,7 +40,7 @@ func EnsurePython3Venv(venv string, packages ...string) (python3 string, err err } python3, err = ensurePython3Venv(venv, packages...) if err != nil { - return "", errors.Wrap(err, "prepare python3 venv failed") + return "", errors.Wrap(code.InvalidPython3Venv, err.Error()) } python3Executable = python3 log.Info().Str("Python3Executable", python3Executable).Msg("set python3 executable path") diff --git a/hrp/loader.go b/hrp/loader.go index 0f75ef95..9d2ecf8c 100644 --- a/hrp/loader.go +++ b/hrp/loader.go @@ -54,7 +54,7 @@ func LoadTestCases(iTestCases ...ITestCase) ([]*TestCase, error) { tc, err := testCasePath.ToTestCase() if err != nil { log.Warn().Err(err).Str("path", path).Msg("load testcase failed") - return nil + return err } testCases = append(testCases, tc) return nil diff --git a/hrp/parser.go b/hrp/parser.go index 290a5f07..34fb4f73 100644 --- a/hrp/parser.go +++ b/hrp/parser.go @@ -125,14 +125,19 @@ func (p *Parser) Parse(raw interface{}, variablesMapping map[string]interface{}) } } -func parseJSONNumber(raw builtinJSON.Number) (interface{}, error) { +func parseJSONNumber(raw builtinJSON.Number) (value interface{}, err error) { if strings.Contains(raw.String(), ".") { // float64 - return raw.Float64() + value, err = raw.Float64() } else { // int64 - return raw.Int64() + value, err = raw.Int64() } + if err != nil { + return nil, errors.Wrap(code.ParseError, + fmt.Sprintf("parse json number failed: %v", err)) + } + return value, nil } const ( @@ -185,18 +190,18 @@ func (p *Parser) ParseString(raw string, variablesMapping map[string]interface{} argsStr := funcMatched[2] arguments, err := parseFunctionArguments(argsStr) if err != nil { - return raw, errors.Wrap(code.ParseStringError, err.Error()) + return raw, errors.Wrap(code.ParseFunctionError, err.Error()) } parsedArgs, err := p.Parse(arguments, variablesMapping) if err != nil { - return raw, errors.Wrap(code.ParseStringError, err.Error()) + return raw, err } result, err := p.callFunc(funcName, parsedArgs.([]interface{})...) if err != nil { log.Error().Str("funcName", funcName).Interface("arguments", arguments). Err(err).Msg("call function failed") - return raw, errors.Wrap(code.ParseStringError, err.Error()) + return raw, errors.Wrap(code.CallFunctionError, err.Error()) } log.Info().Str("funcName", funcName).Interface("arguments", arguments). Interface("output", result).Msg("call function success") @@ -228,7 +233,7 @@ func (p *Parser) ParseString(raw string, variablesMapping map[string]interface{} } varValue, ok := variablesMapping[varName] if !ok { - return raw, errors.Wrap(code.ParseStringError, + return raw, errors.Wrap(code.VariableNotFound, fmt.Sprintf("variable %s not found", varName)) } diff --git a/hrp/plugin.go b/hrp/plugin.go index f28558a2..8e8fc875 100644 --- a/hrp/plugin.go +++ b/hrp/plugin.go @@ -9,8 +9,10 @@ import ( "github.com/httprunner/funplugin" "github.com/httprunner/funplugin/fungo" + "github.com/pkg/errors" "github.com/rs/zerolog/log" + "github.com/httprunner/httprunner/v4/hrp/internal/code" "github.com/httprunner/httprunner/v4/hrp/internal/myexec" "github.com/httprunner/httprunner/v4/hrp/internal/sdk" ) @@ -52,7 +54,7 @@ func initPlugin(path, venv string, logOn bool) (plugin funplugin.IPlugin, err er err = BuildPlugin(pluginPath, genPyPluginPath) if err != nil { log.Error().Err(err).Str("path", pluginPath).Msg("build plugin failed") - return nil, nil + return nil, err } pluginPath = genPyPluginPath @@ -73,6 +75,7 @@ func initPlugin(path, venv string, logOn bool) (plugin funplugin.IPlugin, err er plugin, err = funplugin.Init(pluginPath, pluginOptions...) if err != nil { log.Error().Err(err).Msgf("init plugin failed: %s", pluginPath) + err = errors.Wrap(code.InitPluginFailed, err.Error()) return } diff --git a/hrp/runner_test.go b/hrp/runner_test.go index 383cae09..c07cf1f1 100644 --- a/hrp/runner_test.go +++ b/hrp/runner_test.go @@ -7,6 +7,7 @@ import ( "testing" "time" + "github.com/httprunner/httprunner/v4/hrp/internal/code" "github.com/rs/zerolog/log" "github.com/stretchr/testify/assert" ) @@ -16,7 +17,7 @@ func buildHashicorpGoPlugin() { err := BuildPlugin(tmpl("plugin/debugtalk.go"), tmpl("debugtalk.bin")) if err != nil { log.Error().Err(err).Msg("build hashicorp go plugin failed") - os.Exit(1) + os.Exit(code.GetErrorCode(err)) } } @@ -33,7 +34,7 @@ func buildHashicorpPyPlugin() { err := ioutil.WriteFile(tmpl("debugtalk.py"), src, 0o644) if err != nil { log.Error().Err(err).Msg("copy hashicorp python plugin failed") - os.Exit(1) + os.Exit(code.GetErrorCode(err)) } } diff --git a/hrp/step_request.go b/hrp/step_request.go index 89269d6f..4a25d02e 100644 --- a/hrp/step_request.go +++ b/hrp/step_request.go @@ -21,6 +21,7 @@ import ( "github.com/rs/zerolog/log" "github.com/httprunner/httprunner/v4/hrp/internal/builtin" + "github.com/httprunner/httprunner/v4/hrp/internal/code" "github.com/httprunner/httprunner/v4/hrp/internal/json" "github.com/httprunner/httprunner/v4/hrp/pkg/httpstat" ) @@ -683,7 +684,7 @@ func (s *StepRequest) CallRefCase(tc ITestCase) *StepTestCaseWithOptionalArgs { s.step.TestCase, err = tc.ToTestCase() if err != nil { log.Error().Err(err).Msg("failed to load testcase") - os.Exit(1) + os.Exit(code.GetErrorCode(err)) } return &StepTestCaseWithOptionalArgs{ step: s.step, @@ -696,7 +697,7 @@ func (s *StepRequest) CallRefAPI(api IAPI) *StepAPIWithOptionalArgs { s.step.API, err = api.ToAPI() if err != nil { log.Error().Err(err).Msg("failed to load api") - os.Exit(1) + os.Exit(code.GetErrorCode(err)) } return &StepAPIWithOptionalArgs{ step: s.step, diff --git a/hrp/testcase.go b/hrp/testcase.go index b9733b57..67d0d715 100644 --- a/hrp/testcase.go +++ b/hrp/testcase.go @@ -10,6 +10,7 @@ import ( "github.com/rs/zerolog/log" "github.com/httprunner/httprunner/v4/hrp/internal/builtin" + "github.com/httprunner/httprunner/v4/hrp/internal/code" ) // ITestCase represents interface for testcases, @@ -117,7 +118,8 @@ func (tc *TCase) MakeCompat() (err error) { func (tc *TCase) ToTestCase(casePath string) (*TestCase, error) { if tc.TestSteps == nil { - return nil, errors.New("invalid testcase format, missing teststeps!") + return nil, errors.Wrap(code.InvalidCaseFormat, + "invalid testcase format, missing teststeps!") } if tc.Config == nil { @@ -169,7 +171,8 @@ func (tc *TCase) toTestCase() (*TestCase, error) { if ok { path := filepath.Join(projectRootDir, apiPath) if !builtin.IsFilePathExists(path) { - return nil, errors.New("referenced api file not found: " + path) + return nil, errors.Wrap(code.ReferencedFileNotFound, + fmt.Sprintf("referenced api file not found: %s", path)) } refAPI := APIPath(path) @@ -181,7 +184,8 @@ func (tc *TCase) toTestCase() (*TestCase, error) { } else { apiMap, ok := step.API.(map[string]interface{}) if !ok { - return nil, fmt.Errorf("referenced api should be map or path(string), got %v", step.API) + return nil, errors.Wrap(code.InvalidCaseFormat, + fmt.Sprintf("referenced api should be map or path(string), got %v", step.API)) } api := &API{} err = mapstructure.Decode(apiMap, api) @@ -192,7 +196,8 @@ func (tc *TCase) toTestCase() (*TestCase, error) { } _, ok = step.API.(*API) if !ok { - return nil, fmt.Errorf("failed to handle referenced API, got %v", step.TestCase) + return nil, errors.Wrap(code.InvalidCaseFormat, + fmt.Sprintf("failed to handle referenced API, got %v", step.TestCase)) } testCase.TestSteps = append(testCase.TestSteps, &StepAPIWithOptionalArgs{ step: step, @@ -202,7 +207,8 @@ func (tc *TCase) toTestCase() (*TestCase, error) { if ok { path := filepath.Join(projectRootDir, casePath) if !builtin.IsFilePathExists(path) { - return nil, errors.New("referenced testcase file not found: " + path) + return nil, errors.Wrap(code.ReferencedFileNotFound, + fmt.Sprintf("referenced testcase file not found: %s", path)) } refTestCase := TestCasePath(path) @@ -214,7 +220,8 @@ func (tc *TCase) toTestCase() (*TestCase, error) { } else { testCaseMap, ok := step.TestCase.(map[string]interface{}) if !ok { - return nil, fmt.Errorf("referenced testcase should be map or path(string), got %v", step.TestCase) + return nil, errors.Wrap(code.InvalidCaseFormat, + fmt.Sprintf("referenced testcase should be map or path(string), got %v", step.TestCase)) } tCase := &TCase{} err = mapstructure.Decode(testCaseMap, tCase) @@ -229,7 +236,8 @@ func (tc *TCase) toTestCase() (*TestCase, error) { } _, ok = step.TestCase.(*TestCase) if !ok { - return nil, fmt.Errorf("failed to handle referenced testcase, got %v", step.TestCase) + return nil, errors.Wrap(code.InvalidCaseFormat, + fmt.Sprintf("failed to handle referenced testcase, got %v", step.TestCase)) } testCase.TestSteps = append(testCase.TestSteps, &StepTestCaseWithOptionalArgs{ step: step, @@ -317,7 +325,8 @@ func convertCompatValidator(Validators []interface{}) (err error) { for assertMethod, iValidatorContent := range validatorMap { validatorContent := iValidatorContent.([]interface{}) if len(validatorContent) > 3 { - return fmt.Errorf("unexpected validator format: %v", validatorMap) + return errors.Wrap(code.InvalidCaseFormat, + fmt.Sprintf("unexpected validator format: %v", validatorMap)) } validator.Check = validatorContent[0].(string) validator.Assert = assertMethod @@ -330,7 +339,8 @@ func convertCompatValidator(Validators []interface{}) (err error) { Validators[i] = validator continue } - return fmt.Errorf("unexpected validator format: %v", validatorMap) + return errors.Wrap(code.InvalidCaseFormat, + fmt.Sprintf("unexpected validator format: %v", validatorMap)) } return nil }