/
githubmirror
/
nest
Обзор
Документация
Войти
/
githubmirror
/
nest
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
packages/core/errors/messages.ts
263 строки
10 KB
haredoggy
fix(core): include received value type in invalid-module error
20 май 2026, 13:37
20 май 2026, 13:37
16aceab
Код
Авторство
О чём код?
import type { DynamicModule, ForwardReference, Type } from '@nestjs/common'; import { isNil, isSymbol } from '@nestjs/common/utils/shared.utils'; import { InjectorDependency, InjectorDependencyContext, } from '../injector/injector'; import { Module } from '../injector/module'; /** * Returns the name of an instance or `undefined` * @param instance The instance which should get the name from */ const getInstanceName = (instance: unknown): string => { if ((instance as ForwardReference)?.forwardRef) { return (instance as ForwardReference).forwardRef()?.name; } if ((instance as DynamicModule)?.module) { return (instance as DynamicModule).module?.name; } return (instance as Type)?.name; }; /** * Returns the name of the dependency. * Tries to get the class name, otherwise the string value * (= injection token). As fallback to any falsy value for `dependency`, it * returns `fallbackValue` * @param dependency The name of the dependency to be displayed * @param fallbackValue The fallback value if the dependency is falsy * @param disambiguated Whether dependency's name is disambiguated with double quotes */ const getDependencyName = ( dependency: InjectorDependency | undefined, fallbackValue: string, disambiguated = true, ): string => // use class name getInstanceName(dependency) || // use injection token (symbol) (isSymbol(dependency) && dependency.toString()) || // use string directly (dependency ? disambiguated ? `"${dependency as string}"` : (dependency as string) : undefined) || // otherwise fallbackValue; /** * Returns the name of the module * Tries to get the class name. As fallback it returns 'current'. * @param module The module which should get displayed */ const getModuleName = (module: Module | undefined) => (module && getInstanceName(module.metatype)) || 'current'; const stringifyScope = (scope: any[]): string => (scope || []).map(getInstanceName).join(' -> '); export const UNKNOWN_DEPENDENCIES_MESSAGE = ( type: string | symbol, unknownDependencyContext: InjectorDependencyContext, moduleRef: Module | undefined, ) => { const { index, name, dependencies, key } = unknownDependencyContext; const moduleName = getModuleName(moduleRef); const dependencyName = getDependencyName(name, 'dependency'); const isImportTypeIssue = !isNil(index) && dependencies && (dependencies[index] === undefined || dependencies[index] === Object || (typeof dependencies[index] === 'function' && (dependencies[index] as any).name === 'Object')); let potentialSolutions: string; if (isImportTypeIssue) { potentialSolutions = `\n Potential solutions: - The dependency at index [${index}] appears to be undefined at runtime - This commonly occurs when using 'import type' instead of 'import' for injectable classes - Check your imports and change: ❌ import type { SomeService } from './some.service'; ✅ import { SomeService } from './some.service'; - Ensure the imported class is decorated with @Injectable() or is a valid provider - If using dynamic imports, ensure the class is available at runtime, not just for type checking For more common dependency resolution issues, see: https://docs.nestjs.com/faq/common-errors`; } else { potentialSolutions = // If module's name is well defined moduleName !== 'current' ? `\n Potential solutions: - Is ${moduleName} a valid NestJS module? - If ${dependencyName} is a provider, is it part of the current ${moduleName}? - If ${dependencyName} is exported from a separate @Module, is that module imported within ${moduleName}? @Module({ imports: [ /* the Module containing ${dependencyName} */ ] }) For more common dependency resolution issues, see: https://docs.nestjs.com/faq/common-errors` : `\n Potential solutions: - If ${dependencyName} is a provider, is it part of the current Module? - If ${dependencyName} is exported from a separate @Module, is that module imported within Module? @Module({ imports: [ /* the Module containing ${dependencyName} */ ] }) For more common dependency resolution issues, see: https://docs.nestjs.com/faq/common-errors`; } let message = `Nest can't resolve dependencies of the ${type.toString()}`; if (isNil(index)) { message += `. Please make sure that the "${key!.toString()}" property is available in the current context.${potentialSolutions}`; return message; } const dependenciesName = (dependencies || []).map(dependencyName => getDependencyName(dependencyName, '+', false), ); dependenciesName[index] = '?'; const tokenFragment = !isImportTypeIssue && name !== undefined ? ` ${dependencyName}` : ''; const contextLabel = isImportTypeIssue ? 'current' : moduleName; message += ` (`; message += dependenciesName.join(', '); message += `). Please make sure that the argument${tokenFragment} at index [${index}]`; message += ` is available in the ${contextLabel} module.`; message += potentialSolutions; return message; }; export const INVALID_MIDDLEWARE_MESSAGE = ( text: TemplateStringsArray, name: string, ) => `The middleware doesn't provide the 'use' method (${name})`; export const UNDEFINED_FORWARDREF_MESSAGE = ( scope: Type<any>[], ) => `Nest cannot create the module instance. Often, this is because of a circular dependency between modules. Use forwardRef() to avoid it. (Read more: https://docs.nestjs.com/fundamentals/circular-dependency) Scope [${stringifyScope(scope)}] `; export const INVALID_MODULE_MESSAGE = ( parentModule: any, index: number, scope: any[], receivedValue: unknown, ) => { const parentModuleName = parentModule?.name || 'module'; let formattedValue: string; let receivedType: string; if (receivedValue === null) { formattedValue = 'null'; receivedType = 'null'; } else if (typeof receivedValue === 'string') { formattedValue = `"${receivedValue}"`; receivedType = 'string'; } else { formattedValue = String(receivedValue); receivedType = typeof receivedValue; } return `Nest cannot create the ${parentModuleName} instance. Received an unexpected value at index [${index}] of the ${parentModuleName} "imports" array. The received value \`${formattedValue}\` is of type "${receivedType}". Scope [${stringifyScope(scope)}]`; }; export const USING_INVALID_CLASS_AS_A_MODULE_MESSAGE = ( metatypeUsedAsAModule: Type | ForwardReference, scope: any[], classKind: 'provider' | 'controller' | 'filter', ) => { const metatypeNameQuote = `"${getInstanceName(metatypeUsedAsAModule)}"`; let hint: string; switch (classKind) { case 'controller': hint = `${metatypeNameQuote} is decorated with @Controller() and cannot appear in the "imports" array of a module. Please move ${metatypeNameQuote} to the "controllers" array of the importing module instead.`; break; case 'provider': hint = `${metatypeNameQuote} is decorated with @Injectable() and cannot appear in the "imports" array of a module. Please move ${metatypeNameQuote} to the "providers" array of the importing module instead.`; break; case 'filter': hint = `${metatypeNameQuote} is decorated with @Catch() and cannot appear in the "imports" array of a module. Please move ${metatypeNameQuote} to the "providers" array (using the APP_FILTER token to apply it globally) or apply it via @UseFilters() instead.`; break; } return `${hint} Scope [${stringifyScope(scope)}] `; }; export const UNDEFINED_MODULE_MESSAGE = ( parentModule: any, index: number, scope: any[], ) => { const parentModuleName = parentModule?.name || 'module'; return `Nest cannot create the ${parentModuleName} instance. The module at index [${index}] of the ${parentModuleName} "imports" array is undefined. Potential causes: - A circular dependency between modules. Use forwardRef() to avoid it. Read more: https://docs.nestjs.com/fundamentals/circular-dependency - The module at index [${index}] is of type "undefined". Check your import statements and the type of the module. Scope [${stringifyScope(scope)}]`; }; export const UNKNOWN_EXPORT_MESSAGE = ( token: string | symbol = 'item', module: string, ) => { token = isSymbol(token) ? token.toString() : token; return `Nest cannot export a provider/module that is not a part of the currently processed module (${module}). Please verify whether the exported ${token} is available in this particular context. Possible Solutions: - Is ${token} part of the relevant providers/imports within ${module}? For more common dependency resolution issues, see: https://docs.nestjs.com/faq/common-errors `; }; export const INVALID_CLASS_MESSAGE = (text: TemplateStringsArray, value: any) => `ModuleRef cannot instantiate class (${value} is not constructable).`; export const INVALID_CLASS_SCOPE_MESSAGE = ( text: TemplateStringsArray, name: string | undefined, ) => `${ name || 'This class' } is marked as a scoped provider. Request and transient-scoped providers can't be used in combination with "get()" method. Please, use "resolve()" instead.`; export const UNKNOWN_REQUEST_MAPPING = (metatype: Type) => { const className = metatype.name; return className ? `An invalid controller has been detected. "${className}" does not have the @Controller() decorator but it is being listed in the "controllers" array of some module.` : `An invalid controller has been detected. Perhaps, one of your controllers is missing the @Controller() decorator.`; }; export const INVALID_MIDDLEWARE_CONFIGURATION = `An invalid middleware configuration has been passed inside the module 'configure()' method.`; export const UNHANDLED_RUNTIME_EXCEPTION = `Unhandled Runtime Exception.`; export const INVALID_EXCEPTION_FILTER = `Invalid exception filters (@UseFilters()).`; export const MICROSERVICES_PACKAGE_NOT_FOUND_EXCEPTION = `Unable to load @nestjs/microservices package. (Please make sure that it's already installed.)`;