The docs for ParameterizedQuery state:
The type can be used in place of the query parameter, with any query method directly. And it never throws any error, leaving it for query methods to reject with ParameterizedQueryError.
What exactly does this mean?
does it mean that the constructor of ParameterizedQuery never throws an error or does it never throw when we execute the query?
how are we supposed to handle the errors?
i.e. when are we supposed to throw ParameterizedQueryError?
E.g. currently my function looks like this:
async foo() {
const pq = new ParameterizedQuery({
text: 'Select ..',
values: [repoRequest.limit],
rowMode: 'array'
});
return transaction.manyOrNone(pq);
}
and it seems to work fine (same as with a text-query parameter) - it will also throw an error at execution time, when the query is erronous.
does it mean that the constructor of ParameterizedQuery never throws an error or does it never throw when we execute the query?
Yes. Errors from Parameterized Queries manifest themselves in the same way as with all queries in the library - through promise rejection.
UPDATE
I have removed that sentence from the API documentation, to avoid confusion.
Related
I am trying to create a repository for use cases of FirebaseAuth and can see warnings!
Should I ignore the warning, as it not impacting the app?
OR should I handle it now, and How?
Dart has analyzed your program and found out that you have not handled all cases how the method can exit. This is a potentially a problem since your method signature specifies that you method are returning a Future<User> object.
In your case you have not handled the case where an exception are throw from the createUserWithEmailAndPassword method. If an exception are catch, you ends up with a execution path without any return statement.
In this case, Dart will at runtime just return null so it is not an error. But it is a potential sign of a code error since it it not unlikely that you have forgotten the handling of the exception by not have any return statement.
If it is your intention to just return null in case of an exception, you should therefore have insert return null; in both of your catch blocks (or just at the bottom of your method outside the catch-blocks).
Alternative, you can rethrow the exception if you just want to add some logging but still let the caller to also handle the exception. You can read more about this in the language tour: https://dart.dev/guides/language/language-tour#catch
In either cases, you should describe the behavior in the documentation of the method.
I wonder if someone can clarify when to await and when not to. Consider this code
public Task<List<User>> GetUsersForParent(int someParentId)
{
var qry = Context.Users.Where(u=>u.parent = someParentId)
.OrderBy(u=>u.Surname)
return FilterActive(qry);
}
//Actually in a generic base class, but not important (I don't think)
protected Task<List<T>> FilterActive(IQueryable<T> query) where T: BaseEntity
{
return query.Where( q=>q.Active == true ).ToListAsync();
}
Then it is used like this
var users = await DbHandler.GetUsersForParent(1);
So the calling method is awaited, but the others are not. Is this correct?
Should the method calling the ToListAsync() be awaited? (this I assume is now doing the work)
My reason for this is I am getting the DbContext is being used by a second thread dreaded exception. I am running out of places to look. My understanding is the methods are building up the whole task which is executed, but could this be messing with the dbContext?
Edit re DbContext error
Having narrowed down the potential locations for the issue, via Debug.Print and SQL Query profiling (just in case that helps anyone else) I can see one statement being profiled (the next in profile is logging the exception) and I can see two methods being run via the debug print.
One of these methods is a PermissionsManager which, when constructed, initialises itself and loads the user data. This is constructed when requested via the DI framework.
The other method is the single query on the OnGet() method for the page. It is running a single query to get an entity by ID, it is awaited correctly.
My working theory at the moment is that the Thread running the DI construction and another thread running the Page initialise are colliding.
When I made the PermissionManager just _person = new Person() // await db.users.get(userid) the issue goes away. I could replicate the issue 1 in 2 or 3 times of refresh, and with that commented I could not replicate, despite refreshing the page 30+ times.
So my real question with async / await is probably more about DI injection and is that construction running on a different thread? if so, any best practice to avoid?
So the calling method is awaited, but the others are not. Is this correct?
I generally recommend using the async and await keywords, and only return the tasks directly if the method is extremely simple.
My reason for this is I am getting the DbContext is being used by a second thread dreaded exception. I am running out of places to look. My understanding is the methods are building up the whole task which is executed, but could this be messing with the dbContext?
No. At least, the code you posted cannot cause that exception. Whether the async/await keywords are used, or whether the tasks are returned directly, the methods are asynchronous and they do not attempt to do more than one thing on the dbcontext at once.
It's possible that your problem is further up the stack. Task.WhenAll is a good thing to search for when tracking this down.
Should the method calling the ToListAsync() be awaited? (this I assume is now doing the work)
If you await the contents of either method you will be returning the result type, not Task of result type which means the execution cannot be deferred.
Your error will be coming up because you either have multiple threads interacting with the same instance of DbContext, awaited or no this would cause problems, that or you have some code calling the ToListAsync()-containing method, or another async DbContext operation without awaiting.
Writing an EF data access layer returning Task is fairly dangerous which can shoot you in the foot very easily.
Given your code structure I would recommend a couple small changes:
public async Task<List<User>> GetUsersForParent(int someParentId)
{
var qry = Context.Users.Where(u=>u.parent = someParentId)
.OrderBy(u=>u.Surname);
qry = FilterActive(qry);
return await qry.ToListAsync();
}
protected IQueryable<T> FilterActive(IQueryable<T> query) where T: BaseEntity
{
return query.Where( q=> q.Active == true );
}
Notably here I would avoid returning Task to reduce risks of improper use and potentially intermittent bugs. The base-class method for FilterActive can return IQueryable<T> to apply the filter without triggering the execution of the operation. This way FilterActive can be applied whether you want a List, a Count, or simply do an Exists check.
Overall I would recommend exploring patterns that return IQueryable<TEntity> rather than List<TEntity> etc. as the later results in either a lot of limitations for performance and flexibility, or requires a lot of boiler-plate code to handle things like:
Sorting,
Pagination,
Getting just a Count,
Performing an Exists check,
Configurable filtering,
Selectively eager loading related data, or
Projection to generate efficient queries
Doing this with methods that return List<TEntity> either results in very complex code to support some of the above considerations, has these operations applied post-execution leading to heavier queries than would otherwise be needed, or requires a lot of near-duplicate code to handle each scenario.
So the constructor thing was a red herring. It was a missing await after all, just not where expected and in code that was unchanged.
I tracked down the culprit. There was a method in the basePage which hooked into the Filter of MVC pages. It took the user and loaded their permissions, however, since this loading of user permissions was made async, this method did not get awaited (it didn't need it before as was synchronous). I moved it to one of the async events on the page life cycle and all seems happy now (with a suitable await!). So it was a missing await, but the moral of the story is any time you make a sync method async, check what the heck is actually using it!
I had a certain method that called MongoOperations.find(Query query, Class<T> entityClass, String collectionName), and returned a List<T> as expected. I want to change the method to stream(), in case the number of returned objects from the query is exceptionally large. According to the documentation, there should be an identical signature for stream(), but when I try to call the function with a collectionName, I get an error:
groovy.lang.MissingMethodException: No signature of method: org.springframework.data.mongodb.core.MongoTemplate.stream() is applicable for argument types: (org.springframework.data.mongodb.core.query.Query, java.lang.Class, java.lang.String)
When I remove the collectionName, it runs without error. Could this be an issue of Spring Data versions? How can I solve this?
Thanks.
The overloaded stream method which takes collection name as an argument in MongoOperations is added in Mongo Spring 1.10 version.
The change is covered as part of the ticket. https://jira.spring.io/browse/DATAMONGO-1431
I started using JUnitParams to write parameterized tests and it works awesome. For example, the following test is invoked with false, then with true:
#Test
#Parameters ({ "false", "true" })
public void testBla (boolean foo) throws Exception
...
One minor trouble is that I have a custom rule (as in org.junit.rules.TestRule) that only exists to write some additional information to the logs. What it currently does is
public Statement apply (final Statement statement, final Description description)
{
return new Statement ()
{
public void evaluate () throws Throwable
{
log.info (String.format ("RUNNING TEST %s::%s\n",
description.getClassName (),
description.getMethodName ()));
...
When I have just two parameters as above, it is not a problem that it writes the same name for two executions of one method, I can simply count. However, it would still be useful for the rule to print parameter values, especially if I have more.
So, is it possible to find test parameters from within a custom rule?
my best guess: most parameterized junit plugins using junit's Description object. you should be able to get this object in your rule. but what is in this object and is it enough for your purpose depends on the specific plugin you use. if this one is not good for you, try others
I am trying to use nunits new way of exception handling but I am finding it hard to find information on it and how to also use it with moq.
I have right now moq that throws a exception on a mocked method but I don't know how to use nunit to catch it and look at it.
There's a few different ways to do it; I use Assert.Throws.
var exception = Assert.Throws<YourTypeOfException>(()=> Action goes here);
e.g.
var exception = Assert
.Throws<ArgumentNullException>(()=> new ChimpPuncher(null));
You can then query the exception object further if you want, e.g.
Assert.That(exception.Message, Text.Contains("paramname");
Best way to mention is: [ExpectedException(typeof(ApplicationException))] above the test method.
Why can't you enclose the mocked method call in a try/catch block and catch the specific exception being thrown?