no-callback-literal.js 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. /**
  2. * @author Jamund Ferguson
  3. * See LICENSE file in root directory for full license.
  4. */
  5. "use strict"
  6. module.exports = {
  7. meta: {
  8. docs: {
  9. description:
  10. "ensure Node.js-style error-first callback pattern is followed",
  11. category: "Possible Errors",
  12. recommended: false,
  13. url:
  14. "https://github.com/mysticatea/eslint-plugin-node/blob/v11.1.0/docs/rules/no-callback-literal.md",
  15. },
  16. type: "problem",
  17. fixable: null,
  18. schema: [],
  19. },
  20. create(context) {
  21. const callbackNames = ["callback", "cb"]
  22. function isCallback(name) {
  23. return callbackNames.indexOf(name) > -1
  24. }
  25. return {
  26. CallExpression(node) {
  27. const errorArg = node.arguments[0]
  28. const calleeName = node.callee.name
  29. if (
  30. errorArg &&
  31. !couldBeError(errorArg) &&
  32. isCallback(calleeName)
  33. ) {
  34. context.report({
  35. node,
  36. message:
  37. "Unexpected literal in error position of callback.",
  38. })
  39. }
  40. },
  41. }
  42. },
  43. }
  44. /**
  45. * Determine if a node has a possiblity to be an Error object
  46. * @param {ASTNode} node ASTNode to check
  47. * @returns {boolean} True if there is a chance it contains an Error obj
  48. */
  49. function couldBeError(node) {
  50. switch (node.type) {
  51. case "Identifier":
  52. case "CallExpression":
  53. case "NewExpression":
  54. case "MemberExpression":
  55. case "TaggedTemplateExpression":
  56. case "YieldExpression":
  57. return true // possibly an error object.
  58. case "AssignmentExpression":
  59. return couldBeError(node.right)
  60. case "SequenceExpression": {
  61. const exprs = node.expressions
  62. return exprs.length !== 0 && couldBeError(exprs[exprs.length - 1])
  63. }
  64. case "LogicalExpression":
  65. return couldBeError(node.left) || couldBeError(node.right)
  66. case "ConditionalExpression":
  67. return couldBeError(node.consequent) || couldBeError(node.alternate)
  68. default:
  69. return node.value === null
  70. }
  71. }