{"record":{"id":"995d7e357d91606f","repo":"petkaantonov/bluebird","slug":"expecting-a-function-but-got-s-995d7e","errorCode":null,"errorMessage":"expecting a function but got %s","messagePattern":"expecting a function but got (.+?)","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/method.js","lineNumber":10,"sourceCode":"\"use strict\";\nmodule.exports =\nfunction(Promise, INTERNAL, tryConvertToPromise, apiRejection, debug) {\nvar util = require(\"./util\");\nvar ASSERT = require(\"./assert\");\nvar tryCatch = util.tryCatch;\n\nPromise.method = function (fn) {\n    if (typeof fn !== \"function\") {\n        throw new Promise.TypeError(FUNCTION_ERROR + util.classString(fn));\n    }\n    return function () {\n        var ret = new Promise(INTERNAL);\n        ret._captureStackTrace();\n        ret._pushContext();\n        var value = tryCatch(fn).apply(this, arguments);\n        var promiseCreated = ret._popContext();\n        debug.checkForgottenReturns(\n            value, promiseCreated, \"Promise.method\", ret);\n        ret._resolveFromSyncValue(value);\n        return ret;\n    };\n};\n\nPromise.attempt = Promise[\"try\"] = function (fn) {\n    if (typeof fn !== \"function\") {\n        return apiRejection(FUNCTION_ERROR + util.classString(fn));\n    }","sourceCodeStart":1,"sourceCodeEnd":28,"githubUrl":"https://github.com/petkaantonov/bluebird/blob/c220cfe480868e2f5c5de4fe8bb3b04b97588d7f/src/method.js#L1-L28","documentation":"Promise.method(fn) wraps a (possibly throwing/sync) function so it always returns a promise. It validates up front that fn is a function, throwing Promise.TypeError('expecting a function but got %s'). This shifts 'not a function' failures from runtime call time to wrap time with a clear message.","triggerScenarios":"Promise.method(undefined/null/string/object) — passing an undefined handler due to failed import, passing the result of fn() instead of fn, passing an object property that doesn't exist, or passing a class where an instance method was intended.","commonSituations":"Refactor renamed the wrapped function leaving undefined; passing this.method unbound vs bound confusion; loading handlers from config/registry that returned nothing; interop where a module default export is an object not a function.","solutions":["Ensure the argument is a function: check typeof fn === 'function' before wrapping","Fix imports/typos so the identifier resolves to the intended function","Pass the function reference, not an invocation: Promise.method(doWork) not Promise.method(doWork())","If input may be absent, guard: fn ? Promise.method(fn) : fallbackFn"],"exampleFix":"// before\nconst read = Promise.method(config.reader); // undefined\n// after\nif (typeof config.reader !== 'function') throw new Error('reader missing');\nconst read = Promise.method(config.reader);","handlingStrategy":"type-guard","validationCode":"function safeMethod(fn) {\n  if (typeof fn !== 'function') throw new TypeError('Promise.method expects a function, got: ' + fn);\n  return Promise.method(fn);\n}","typeGuard":"function isCallable(fn) {\n  return typeof fn === 'function';\n}","tryCatchPattern":"let wrapped;\ntry {\n  wrapped = Promise.method(handler);\n} catch (e) {\n  if (e instanceof Promise.TypeError) {\n    console.error('handler is not a function, got:', typeof handler);\n    wrapped = () => Promise.reject(e);\n  } else throw e;\n}","preventionTips":["Pass the function reference, not its invocation result","Validate config/registry-provided handlers are functions before wrapping","Check imports when 'undefined' appears in the error message","Bind instance methods before passing them to Promise.method"],"tags":["typeerror","promise-method","type-check"],"backgroundTag":"expecting-a-function","analyzedSha":"c220cfe480868e2f5c5de4fe8bb3b04b97588d7f","analyzedAt":"2026-09-02T02:30:20.863Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}