{"record":{"id":"5eea39390214378c","repo":"oxc-project/oxc","slug":"expected-throw-instead-of-promise-reject","errorCode":null,"errorMessage":"Expected throw instead of Promise.reject","messagePattern":"Expected throw instead of Promise\\.reject","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"warning","filePath":"crates/oxc_linter/src/rules/promise/no_return_wrap.rs","lineNumber":32,"sourceCode":"use oxc_ast_visit::VisitJs;\nuse oxc_diagnostics::OxcDiagnostic;\nuse oxc_macros::declare_oxc_lint;\nuse oxc_span::Span;\nuse schemars::JsonSchema;\nuse serde::Deserialize;\n\nfn no_return_wrap_diagnostic(span: Span, issue: &ReturnWrapper) -> OxcDiagnostic {\n    let warn_msg = match issue {\n        ReturnWrapper::Resolve => \"Avoid wrapping return values in Promise.resolve\",\n        ReturnWrapper::Reject => \"Expected throw instead of Promise.reject\",\n    };\n\n    let help_msg = match issue {\n        ReturnWrapper::Resolve => \"Return the value being passed into Promise.resolve instead\",\n        ReturnWrapper::Reject => \"Throw the value being passed into Promise.reject instead\",\n    };\n\n    OxcDiagnostic::warn(warn_msg).with_help(help_msg).with_label(span)\n}\n\n#[derive(Debug, Default, Clone, JsonSchema, Deserialize)]\n#[serde(rename_all = \"camelCase\", default, deny_unknown_fields)]\npub struct NoReturnWrap {\n    /// `allowReject` allows returning `Promise.reject` inside a promise handler.\n    ///\n    /// With `allowReject` set to `true` the following are examples of correct code:\n    ///\n    /// ```js\n    /// myPromise().then(\n    ///   function() {\n    ///     return Promise.reject(0)\n    /// })\n    /// ```\n    ///\n    /// ```js\n    /// myPromise().then().catch(() => Promise.reject(\"err\"))","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/promise/no_return_wrap.rs#L14-L50","documentation":"Diagnostic from the oxlint rule `promise/no-return-wrap` (plugin `promise`) for the Reject variant. It flags `return Promise.reject(e)` inside a promise handler. The idiomatic equivalent is `throw e`: throwing propagates through the chain to the next `catch` with better stack information in some engines, while a returned rejected promise is a second-class way to signal failure from a handler. Setting `{ \"allowReject\": true }` in the rule config makes returning `Promise.reject` legal (the rule's doc comment documents exactly this escape hatch).","triggerScenarios":"`promise.catch(err => { return Promise.reject(new Error('wrapped')) })`; `then(val => { if (!val) return Promise.reject(new Error('missing')) })` with default `allowReject: false`.","commonSituations":"Error-mapping code inside `catch` handlers; guard clauses written before the team standardized on `throw`; codebases that deliberately prefer `Promise.reject` and need the `allowReject` config.","solutions":["Replace with `throw`: `throw new Error(...)` inside the handler","If the team convention is returning `Promise.reject`, set `{ \"allowReject\": true }` in the rule configuration","Rethrow the original error with context: `throw new Error('context', { cause: err })`"],"exampleFix":"// before\npromise.catch(err => {\n  return Promise.reject(new Error('wrapped: ' + err.message))\n})\n\n// after\npromise.catch(err => {\n  throw new Error('wrapped: ' + err.message)\n})","handlingStrategy":"validation","validationCode":"npx oxlint --promise/no-return-wrap src/\n# team convention prefers returning Promise.reject? permit it:\n#   { \"rules\": { \"promise/no-return-wrap\": [\"error\", { \"allowReject\": true }] } }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Signal failure from handlers with `throw`, reserve `return` for values","If the codebase standardizes on `return Promise.reject`, set `allowReject: true` once in shared config","Rethrow with context (`new Error('ctx', { cause: err })`) instead of wrapping via Promise.reject"],"tags":["promise","async","lint","error-handling","oxlint"],"backgroundTag":"promise-reject-instead-of-throw","analyzedSha":"e1e7af627c8843ab64044ed466b128fcc21a035b","analyzedAt":"2026-08-20T07:01:07.079Z","contentChangedAt":"2026-08-20T07:01:07.079Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}