Skip to content

Commit c1971f9

Browse files
fix(schema-generator): throw error when type is ambiguous
1 parent 8210c64 commit c1971f9

File tree

6 files changed

+36
-14
lines changed

6 files changed

+36
-14
lines changed

lib/decorators/prop.decorator.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as mongoose from 'mongoose';
2+
import { CannotDetermineTypeError } from '../errors';
23
import { RAW_OBJECT_DEFINITION } from '../mongoose.constants';
34
import { TypeMetadataStorage } from '../storages/type-metadata.storage';
45

@@ -29,7 +30,10 @@ export function Prop(options?: PropOptions): PropertyDecorator {
2930
} else if (type && type !== Object) {
3031
options.type = type;
3132
} else {
32-
options.type = mongoose.SchemaTypes.Mixed;
33+
throw new CannotDetermineTypeError(
34+
target.constructor?.name,
35+
propertyKey as string,
36+
);
3337
}
3438
}
3539

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export class CannotDetermineTypeError extends Error {
2+
constructor(hostClass: string, propertyKey: string) {
3+
super(
4+
`Cannot determine a type for the "${hostClass}.${propertyKey}" field (union/intersection/ambiguous type was used). Make sure your property is decorated with a "@Prop({ type: TYPE_HERE })" decorator.`,
5+
);
6+
}
7+
}

lib/errors/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './cannot-determine-type.error';

lib/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export * from './common';
22
export * from './decorators';
3+
export * from './errors';
34
export * from './factories';
45
export * from './interfaces';
56
export * from './mongoose.module';

tests/e2e/schema-definitions.factory.spec.ts

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import * as mongoose from 'mongoose';
22
import { DefinitionsFactory, Prop, raw, Schema } from '../../lib';
3+
import { CannotDetermineTypeError } from '../../lib/errors';
34

45
@Schema()
56
class ChildClass {
@@ -18,9 +19,6 @@ class ExampleClass {
1819
@Prop({ required: true })
1920
name: string;
2021

21-
@Prop({ required: true })
22-
object: object;
23-
2422
@Prop()
2523
buffer: mongoose.Schema.Types.Buffer;
2624

@@ -59,7 +57,7 @@ class ExampleClass {
5957
@Prop(raw({ custom: 'literal', object: true }))
6058
customObject: any;
6159

62-
@Prop()
60+
@Prop({ type: mongoose.Schema.Types.Mixed })
6361
any: any;
6462

6563
@Prop()
@@ -77,10 +75,6 @@ describe('DefinitionsFactory', () => {
7775
required: true,
7876
type: String,
7977
},
80-
object: {
81-
required: true,
82-
type: mongoose.SchemaTypes.Mixed,
83-
},
8478
nodes: [
8579
{
8680
id: {
@@ -104,7 +98,7 @@ describe('DefinitionsFactory', () => {
10498
},
10599
},
106100
},
107-
any: { type: mongoose.SchemaTypes.Mixed },
101+
any: { type: mongoose.Schema.Types.Mixed },
108102
array: { type: [] },
109103
customArray: [{ custom: 'literal', object: true }],
110104
customObject: { custom: 'literal', object: true },
@@ -122,4 +116,19 @@ describe('DefinitionsFactory', () => {
122116
number: { type: Number },
123117
});
124118
});
119+
120+
it('should throw an error when type is ambiguous', () => {
121+
try {
122+
class AmbiguousField {
123+
@Prop()
124+
randomField: object | null;
125+
}
126+
DefinitionsFactory.createForClass(AmbiguousField);
127+
} catch (err) {
128+
expect(err).toBeInstanceOf(CannotDetermineTypeError);
129+
expect(err.message).toEqual(
130+
'Cannot determine a type for the "AmbiguousField.randomField" field (union/intersection/ambiguous type was used). Make sure your property is decorated with a "@Prop({ type: TYPE_HERE })" decorator.',
131+
);
132+
}
133+
});
125134
});

tests/src/event/event.service.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Injectable } from '@nestjs/common';
2-
import { Model, Document } from 'mongoose';
2+
import { Document, Model } from 'mongoose';
33
import { InjectModel } from '../../../lib';
44
import { CreateClickLinkEventDto } from './dto/create-click-link-event.dto';
55
import { CreateSignUpEventDto } from './dto/create-sign-up-event.dto';
@@ -13,10 +13,10 @@ export class EventService {
1313
) {}
1414

1515
async create(
16-
createCatDto: CreateClickLinkEventDto | CreateSignUpEventDto,
16+
createDto: CreateClickLinkEventDto | CreateSignUpEventDto,
1717
): Promise<Event> {
18-
const createdCat = new this.eventModel(createCatDto);
19-
return createdCat.save();
18+
const createdEvent = new this.eventModel(createDto);
19+
return createdEvent.save();
2020
}
2121

2222
async findAll(): Promise<Event[]> {

0 commit comments

Comments
 (0)