Connection awareness - prisma

Is there a way to be aware of connection status with Prisma?
I understand it does everything automatically so I don't have to worry about anything related to connection.
But what if I want to?
Basically I miss two things:
Catchable event. Either client.on('disconnected', ...) or implementing an interface (e.g. onDisconnected() { ... })
$connect() throwing error if it can not connect. No exception raised when DB is not started and I start the application.
// Context:
// - DB not started yet
try {
await client.$connect();
console.log('DB connected');
} catch (e) {
console.log('DB is unavailable');
}
// Output
//
// > DB connected
My use case: I would like to send a system message to maintainers and shut the whole service down if the DB stopped and could not recover connection within a time frame.

Okay, I was able to overcome it. I guess it's rather a bug than a feature.
So $connect() does not throw error it could connect successfully before but the DB has been stopped meanwhile and $disconnect() was not called.
So, calling $disconnect() when lost connection is recognized resulted in $connect() throwing error if still not able to connect.
I still miss the ability to watch for connection events but this is enough for me now.

Related

Catching error messages before server starts

I have a language server set up in an extension that delegates a few commands from the client to the server. They work perfectly when the extension is working but the server takes a second or so to start. If the user happens to press the shortcut that triggers such a command during this time, VSC automatically shows a command XXX not found error message, what is actually true, the command is not yet found. But I would like to catch this situation to provide my own, more appropriate error message. Where can I do so? I tried to add a try/catch to my middleware, eg:
executeCommand: async (command, args, next) => {
try {
return next(command, args);
} catch (error) {
vscode.window.showErrorMessage('Server communication error');
}
}
but this isn't called, either, during the starting period, only later.

Why doesn't my db.collection.insert work?

I am encountering a weird issue here...
After I seem to successfully insert some data into my db.collection I cant seem to get it to reflect using db.collection.find().fetch().
Find below the code I insert into my chrome console:
merchantReviews.insert({merchantScore: "5.5"}, function() {
console.log("Review value successfully inserted");
});
This yields:
"9sd5787kj7dsd98ycnd"
Review value successfully inserted
I think returned value "9sd5787kj7dsd98ycnd" is an indication of a successful db collection insert. Then when I run:
merchantReviews.find().fetch()
I get:
[]
Can anyone tell me what is going on here?
Looking forward to your help.
There are two possibilities here: either the insert fails on the server even though it passes on the client, or you haven't subscribed to your collection.
In case the insert fails on server (most likely due to insufficient permissions, if you have removed the insecure package but have not declared any collection.allow rules), the client code still returns the intended insert ID (in your case, "9sd5787kj7dsd98ycnd"). The callback is called once the server has confirmed that the insert has either failed or succeeded. If it has failed, the callback is called with a single error argument. To catch this, you can instead insert the document like this:
merchantReviews.insert({merchantScore: "5.5"}, function(error) {
if (error) {
console.error(error);
} else {
console.log("Review value successfully inserted");
}
});
If this still logs successful insert, then you haven't subscribed to the collection, and you have removed the autopublish package. You can read about Meteor publish-subscribe system here. Basically, you have to publish the collection in server-side code:
Meteor.publish('reviews', function () {
return merchantReviews.find();
});
And in server code (or your js console) you need to subscribe to the collection with Meteor.subscribe('reviews'). Now calling merchantReviews.find().fetch() should return all documents in the collection.

C# MVC5 classic ADO.NET when to open connection

I'm using MVC5 with classic ADO.NET objects such as sqldatareader and sqldataadapter and sqlconnection and so on....
My controllers are creating a connection while initializing because I need to send the request object to the class holding the sqlconnection for something irrelevant to the question so my controller has an override void
protected override void Initialize(RequestContext requestContext)
{
base.Initialize(requestContext);
db = new db(Request);
db.Connect();
}
Where db is my class and the method (connect) will create the sqlconnection object and open a connection...
and to close the connection I used the controller's dispose method as follows
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (db != null)
{
db.Close();
db = null;
}
}
and everything works fine then at one moment I got a weird server error (can't connect to db) please notice that my host is smarterasp.net
I can connect to database remotely using my home computer and I can connect to the web host as well so the problem is between my webhost and my database host, or between my application and my database host...
or it could be something related to the connection pooling even though the server error doesn't give me any details or stack trace(hens error is not inside my app thread)....
and I've fixed the problem by opening (remote iis) tab of smarterasp.net's control panel and clicked on (fix ACL) which I have no idea what it does but it fixed my problem.... temporarily :( unfortunately the problem reoccurred many times after that
so my question is in short format
is it good practice to open the connection while I'm initializing the controller and close it while the controller disposing???
and what do you think the error reason is??
finally I want to apologize if the question wasn't clear enough because English is not my first language (obviously)....
thanks a lot
so my question is in short format is it good practice to open the
connection while I'm initializing the controller and close it while
the controller disposing???
I do not think that is a good approach. You shouldn't open / close database connections and / or access the database from your controller. The controller should be as "thin" as possible. Additionally - the connection should be kept open for as short a period of time as possible and let ADO.NET connection pooling handle the details for you.
I also recommend wrapping your connection in a using block as it will implicitly call the close method:
using (SqlConnection connection = new SqlConnection(
connectionString))
{
SqlCommand command = new SqlCommand(queryString, connection);
command.Connection.Open();
command.ExecuteNonQuery();
}
You did not say what the exact error is. At first glance, you aren't even checking to see if the connection is open before you try closing it. You should check the connection state before you try to explicitly close it and this should happen outside of the controller. Though I recommend that you wrap your SqlConnection in a using block (mentioned above).
EDIT
I read your comment. You are trying to manage the connection within the context of the controller's lifecycle and I suspect this is your issue.
If you were using Entity Framework (or possibly an another ORM), an IoC with "per-request lifestyle" - then the IoC container would properly dispose your context (connection) at the end of each request, and serve a new instance at each new one.
Perhaps this an option you can explore if you want to manage your database connection this way.

"ERROR: 57014: canceling statement due to user request" Npgsql

I am having this phantom problem in my application where one in every 5 request on a specific page (on an ASP.NET MVC application) throws this error:
Npgsql.NpgsqlException: ERROR: 57014: canceling statement due to user request
at Npgsql.NpgsqlState.<ProcessBackendResponses>d__0.MoveNext()
at Npgsql.ForwardsOnlyDataReader.GetNextResponseObject(Boolean cleanup)
at Npgsql.ForwardsOnlyDataReader.GetNextRow(Boolean clearPending)
at Npgsql.ForwardsOnlyDataReader.Read()
at Npgsql.NpgsqlCommand.GetReader(CommandBehavior cb)
...
On the npgsql github page I found the following bug report: 615
It says there:
Regardless of what exactly is happening with Dapper, there's
definitely a race condition when cancelling commands. Part of this is
by design, because of PostgreSQL: cancel requests are totally
"asynchronous" (they're delivered via an unrelated socket, not as part
of the connection to be cancelled), and you can't restrict the
cancellation to take effect only on a specific command. In other
words, if you want to cancel command A, by the time your cancellation
is delivered command B may already be in progress and it will be
cancelled instead.
Although they have made "changes to hopefully make cancellations much safer" in Npgsql 3.0.2 my current code is incompatible with this version because the need of migration described here.
My current workaround (stupid): I have commented the code in Dapper that says command.Cancel(); and the problem seems to be gone.
if (reader != null)
{
if (!reader.IsClosed && command != null)
{
//command.Cancel();
}
reader.Dispose();
reader = null;
}
Is there a better solution to the problem? And secondly what am I loosing with the current fix (except that I have to remember the change every time I update Dapper)?
Configuration:
NET45,
Npgsql 2.2.5,
Postgresql 9.3
I found why my code didn't dispose the reader, resulting in calling command.Cancel(). This only happens with QueryMultiple method when not every refcursor is read.
Changing the code from:
using (var multipleResults = connection.QueryMultiple("schema.getuserbysocialsecurity", new { socialSecurityNumber }))
{
var client = multipleResults.Read<Client>().SingleOrDefault();
if (client != null)
{
client.Address = multipleResults.Read<Address>().Single();
}
return client;
}
To:
using (var multipleResults = connection.QueryMultiple("schema.getuserbysocialsecurity", new { socialSecurityNumber }))
{
var client = multipleResults.Read<Client>().SingleOrDefault();
var address = multipleResults.Read<Address>().SingleOrDefault();
if (client != null)
{
client.Address = address;
}
return client;
}
This fixed the issue and now the reader is properly disposed and command.Cancel() is not invoked.
Hope this helps anyone else!
UPDATE
The npgsql docs for version 2.2 states:
Npgsql is able to ask the server to cancel commands in progress. To do
this, call the NpgsqlCommand’s Cancel method. Note that another thread
must handle the request as the main thread will be blocked waiting for
command to finish. Also, the main thread will raise an exception as a
result of user cancellation. (The error code is 57014.)
I have also posted an issue on the Dapper github page.

Execution stops on Cookies.getCookie() call with no exceptions

I'm trying to read a Cookie value in my server side implementation class. After some debugging my code now looks like this:
logger.info("Initiating login");
String oracleDad;
try {
logger.info("inside try");
oracleDad = Cookies.getCookie("dad");
logger.info("Read dad from cookie: " + oracleDad);
} catch (Exception e) {
logger.error("Failed to read dad from cookie", e);
oracleDad = "gtmd";
}
When I execute this code my onFailure block is fired with a Status code Exception:
com.google.gwt.user.client.rpc.StatusCodeException: 500 The call
failed on the server; see server log for details
My logging output on the server looks like this:
[INFO] c.g.e.server.rpc.MyProjectImpl - Initiating login
[INFO] c.g.e.server.rpc.MyProjectImpl - inside try
How is it possible that neither logger, the INFO or the ERROR, fire after the Cookies.getCookie() call? I'd hoped that by adding the catch(Exception e) I'd get some error message explaining why the code fails. But execution just seems to stop silently.
I'm using com.google.gwt.user.client.Cookies. I thought client code can be run on the server, just not vice versa. Is that correct? Is there something else I'm missing?
I'm using com.google.gwt.user.client.Cookies. I thought client code can be run on the server, just not vice versa. Is that correct? Is there something else I'm missing?
No, that's not correct, yes there is something you are missing: Server code can't run on the client, and client code can't run on the server.
You are not getting an Exception. You are getting an Error or some other Throwable.
Try catching Throwable in your try/catch block, and you'll see that you are getting an error where the server JVM is unable to load the Cookies class, because something is wrong. The JVM thinks that a native library is missing (because it doesn't know what JSNI is or how to run it), so it throws an UnsatisfiedLinkError:
Thrown if the Java Virtual Machine cannot find an appropriate native-language definition of a method declared native.
In GWT, the Cookies class is meant to interact with the browser itself to see what cookies have been defined on the currently loaded page. To use cookies on a J2EE server, ask the HttpServletRequest object for the cookies it knows about, and their values.