question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Don't throw error when passing objects with additional fields

See original GitHub issue

Problem

Typescript actively uses duck typing, which allows us to significantly reduce the amount of code in comparison with other languages, since we do not need to write many adapters and intermediate classes, while still guaranteeing full-fledged type safety. However, I came across an unpleasant feature of the prisma, which throws an error in cases when I pass to methods, for example create, objects that have extra fields. However, in theory, this does not prevent the prisma from correctly interpreting and executing a query to the database. We already have a large project, which we will transfer from typeORM to prisma. TypeORM was type-insecure, but it allowed the transfer of objects with extra fields. As a result, it turns out that now we need to make up to hundreds of new classes that will not do anything, but will just exactly match the shape of the prism models. For example, in DB(respectively in prisma) we have model User, with next fields: (userId, userName, password). And from client I getting similar object with type UserDto , with next fields: (userName, password, timestamp). And I want to save it to DB, but without timestamp. Prisma throw error in runtime and say that object have unknown fields timestamp. But it have compiled successfully

Suggested solution

Since the situation is not lonely, and there are a lot of such places in the code, it seems to me that the best solution would be to simply remove this error, since the extra fields do not interfere with the correct request, but can only indirectly say that the user may , transfers the wrong object that it wants, and in most cases it learns about it at the compilation stage, due to duck typing. But, we don’t have to write tons of intermediate classes, adapters, transfers, etc.

Alternatives

if you think that this is a problem, it seems to me that you should at least not let the application compile if objects of types with extra fields are passed. Since it was a big surprise for me that the application crashed at runtime, having received a type object with extra fields, because this was the expected behavior, the types are defined in the code

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:13
  • Comments:9 (1 by maintainers)

github_iconTop GitHub Comments

3reactions
KieranHarpercommented, Jun 16, 2022

It’s a good question and I think this problem is essentially with Typescript, since it can come up in other ways too. For example a rest api can accidentally return extra (private) data if a larger type is spread from an upstream stage. I’m not super close to the development of the language but it looks like it’s an ongoing thing people want to improve: https://github.com/microsoft/TypeScript/issues/12936#issuecomment-1117135412

If you’re writing typescript you’re pretty much assuming that everything that’s true at build time is true at run time – it’s a build time mindset. The spread operator to me always means “take the fields you need from this to satisfy the type of the input”. Rather than “overload the object beyond its type to include everything in this” (which is unfortunately the actual result). If I was a pure JS programmer maybe I would always think the other way around!

When I’m writing code to interact with Prisma I’m super happy because it has really great typings that ensure that things make sense at build time based on the schema. From that perspective Prisma is already preventing me from asking it to accept data that isn’t in the schema.

At runtime I think Prisma needs to check the types of some fields and throw errors, because not doing so will cause data problems or result in less friendly DB errors being thrown. But checking for excess fields is complaining about something that can’t do any damage and isn’t the programmer’s intent.

A subtle subset of the spread operator problem is where the extra fields caught by the spread at runtime are actually valid in the schema… In that case it would not error but it would do damage (because what I think I’m doing at build time isn’t what I’m actually doing at runtime). Don’t think there’s anything Prisma can do about that situation tho, unless perhaps with a future version of typescript.

Maybe allowing us to opt out of strict excess field checking would be enough to make it safer at runtime? To be clear I mean safety in terms of less crashes - the data safety is the same either way.

2reactions
aeddie-zapidhirecommented, Aug 3, 2022

@KieranHarper

In that case it would not error but it would do damage …

Unit testing is really the only way to improve safety on that because it’s implementation specific.

Have to say this error (throwing at runtime) caught me by surprise (fortunately my e2e tests caught it before it went out).

Read more comments on GitHub >

github_iconTop Results From Across the Web

Pass an object with JS throw new Error in node - Stack Overflow
The constructor for an Error object expects a string, not an object (which is why your scheme doesn't work). You are free to...
Read more >
Error handling - Apollo GraphQL Docs
Whenever you throw a GraphQLError , you can add arbitrary fields to the error's extensions object to provide additional context to the client....
Read more >
Custom errors, extending Error - The Modern JavaScript Tutorial
JavaScript allows to use throw with any argument, so technically our custom error classes don't need to inherit from Error .
Read more >
Error - JavaScript - MDN Web Docs - Mozilla
Error objects are thrown when runtime errors occur. The Error object can also be used as a base object for user-defined exceptions.
Read more >
Best Practices for exceptions - .NET - Microsoft Learn
Throw an InvalidOperationException exception if a property set or method call isn't appropriate given the object's current state. · Throw an ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found