Microsoft Dynamics NAV: Error Message Log - microsoft-dynamics

I'm still new to using Dynamics NAV and I'm still a junior Dev so I have a few questions:
I need to be able to Log error messages in NAV as they happen, I have the following fields in a table:
1 Entry No. Integer
2 Error Message Integer
3 Object ID Integer
4 Session ID Integer
5 User ID Integer
6 Object Name Text 250
It needs to log that information when an error occurs, I'm not really sure how to do it.

I'm not sure if you are trying to log errors in a specific object you are working on.
Typically, I use
String := GETLASTERRORTEXT
in my custom code, when calling other Codeunits. This will give you the error description, which you can insert into your custom error log table.
Here is the documentation:
https://learn.microsoft.com/en-us/dynamics-nav/getlasterrortext-function

Related

How to check if a CRecordset field has already been fetched?

I'm using a CDatabase*/CRecordset* duo to read a HFSQL (windev) database through an ODBC DSN.
There are many issues with HFSQL's handling of binary blobs, especially when they're empty.
One such problem causes my app to fire warnings and exceptions on loop as I read a table. I use a custom class that manages the recordset and fetches every field once, in ascending ordinal order, and stores the resulting CDBVariant vars in a vector for my own later uses. The error I get alternates between Warning: ODBC Success With Info on field 8. when the field has content and Error: GetFieldValue operation failed on field 8. Data already fetched for this field. when it has none. Clearly, I have not fetched the field before, so either the wrong error message is displayed or the CRecordset believes it is correct and I should be able to detect it beforehand.
How could I go about detecting whether my CRecordset considers a field to have already been fetched? GetODBCFieldInfo does not give me any useful information, have I missed something?

PowerBI subscription error : there is no data for the field at position x

We have run a PowerBI subscription to generate visualisations report in PDF format we have get many errors like this
There is no data for the field at position x
The problem is we searched many times about it we found that it may occurred due to missing data in dataset.
But we have about 30 datasets with a query to oracle database we cannot figure out which is the missing data and the log does not mention which report causes the error.
Is there a way to figure out which field is missing?
Or is there a way to enrich the reports error log to give us which report failed?
A sample of exact error is repeated with different positions :
processing!ReportServer_0-8!1e18!02/07/2022-09:56:36:: e
ERROR: Throwing Microsoft.ReportingServices.ReportProcessing.ReportProcessingException: , Microsoft.ReportingServices.ReportProcessing.ReportProcessingException: There is no data for the field at position 29.;
Dears
I found a solution help me. I will share it.
The error is due to missing data, not missing values, which means the column name defined in the data set field has been changed in the database.
note:
When make the value equals null it will not give the same error; even if it is used in the report it will give a different error.
about how to detect ?
Simply install report builder in machine has connection to this database and open this report with report builder and make verify fields, it will give detailed error with the name of dataset fields not found so we tracked it in database we found it has been changed so fix it in either dataset or column name in database it fix the issue.
New challenge we are going to handle it either column name exist or changed to e, never get error and give empty report better as there is some database the report will connect may not have the same column names so it should give empty part of report instead of error.
thanks BR,

Get only MQ9 messages that belong to a group "2" in C++

I am trying to use IBM MQ client 9 with C++. I would like to read only messages that has group id '2'. I have tried everything but it just does not work. Can someone assist please?
I tried to set groupId and flag to match on group.
MQGET
gmoptions.setMatchOptions(MQMO_MATCH_GROUP_ID);
MQBYTE24 bGroupId("2");
ImqBinary _groupId;
_groupId.set(bGroupId, sizeof(bGroupId));
message.setGroupId(_groupId);
q->get(message, gmoptions);
MQPUT
MQBYTE24 bGroupId("2");
ImqBinary _groupId;
_groupId.set(bGroupId, sizeof(bGroupId));
message.setGroupId(_groupId);
ImqPutMessageOptions pmo;
pmo.setOptions(MQPMO_LOGICAL_ORDER);
pmo.setRecordFields(MQPMRF_GROUP_ID);
q->put(message, pmo);
mqget should be able to get all the msgs with groupId "2" but it does not. Though it can read the msg as soon as I remove setMatchOptions.
Basically, I want to use Group Id as filter where server instance 1 will read msgs only in group1 and server instance 2 will read msgs only in group 2 and so on, instead of creating separate queues for each server instance.
May be following can help me if group id is only for batching instead of filtering though not sure how to do 'Selection using the MQSUB and MQOPEN function calls' in C++
https://www.ibm.com/support/knowledgecenter/SSFKSJ_9.0.0/com.ibm.mq.dev.doc/q022990_.htm
Is there any C++ equivalent of MQSETMP ? I am unable to find any interface in ImqQueue or ImqObject that will let me set message property or selectionString.
I don't think you are going about this the right way.
IBM published a Java/MQ sample program to get messages in a group called GetGroup.java. You can find it here. You can use it as a model for your C++ program.
Basically, the code retrieves a message from the queue and then checks the messageFlags field if the message is part of a group.
if ((myMessage.messageFlags & CMQC.MQMF_MSG_IN_GROUP) == CMQC.MQMF_MSG_IN_GROUP)
If the message is part of the group then the code sets the matchOptions for matching on a group and retrieves all of the messages in the group.
Note: You will probably want to add logical order to the GMO options.
gmo.options |= CMQC.MQGMO_LOGICAL_ORDER;
Finally, what is this?
pmo.setRecordFields(MQPMRF_GROUP_ID);
That doesn't make any sense. You should be setting messageFlags field to MQMF_MSG_IN_GROUP.
You can use the concept of SELECTORS in IBM MQ. A message selector is a variable-length string used by an application to register its interest in only those messages that have properties that satisfy the Structured Query Language (SQL) query that the selection string represents.
A message selector is a concept that has been in the JMS specification for a long time. It
is a way of limiting the messages that are passed to an application to those that meet
certain criteria. Those criteria are based on the values of the message properties and only
the value of the message properties. It is important to understand that selection cannot be
based on any values of the message payload, only on the message property values.
In your case, the PUT application will have to put messages with populating the a certain topic string in MQMD or MQRFH2 header and using MQ Interface function calls, you should be able to pick the messages only with a certain value which in your case is GroupId value.
Below are few reference links to the concept:
https://www.ibm.com/support/knowledgecenter/SSFKSJ_7.5.0/com.ibm.mq.dev.doc/q022990_.htm
http://publib.boulder.ibm.com/infocenter/ieduasst/v1r1m0/topic/com.ibm.iea.wmq_v7/wmq/7.0/MQI/iea_330_wmqv7_API_3_Selectors.pdf ==> Pdf gets downloaded
To understand Message Properties => https://www.ibm.com/support/knowledgecenter/en/SSFKSJ_8.0.0/com.ibm.mq.dev.doc/q022920_.htm

How to get constraint errors from OCIErrorGet?

Our C++ program is using Oracle and OCI to do its database work. Occasionally, the user will trigger a constraint violation, which we detect and then show an error message from OCIErrorGet. OCIErrorGet returns strings like this:
ORA-02292: integrity constraint (MYSCHEMA.CC_MYCONSTRAINT) violated - child record found
ORA-06512: at line 5
I am looking for the cleanest way to extract "MYSCHEMA.CC_MYCONSTRAINT" from the Oracle error. Knowing the name of the constraint, I could show a better error message (our code could look up a very meaningful error message if it had access to the constraint name).
I could use a regex or something and assume that the Oracle message will never change, but this seems a little fragile to me. Or I could look for specific ORA codes and then grab whatever text falls between the parentheses. But I was hoping OCI had a cleaner/more robust way, if a constraint fails, to figure out the actual name of the failed constraint without resorting to hardcoded string manipulation.
Any ideas?
According to the Oracle Docs, a string search is exactly what you need to do:
Recognizing Variable Text in Messages
To help you find and fix errors, Oracle embeds object names, numbers,
and character strings in some messages. These embedded variables are
represented by string, number, or character, as appropriate. For
example:
ORA-00020: maximum number of processes (number) exceeded
The preceding message might actually appear as follows:
ORA-00020: maximum number of processes (50) exceeded
Oracle makes a big point in their docs of saying the strings will be kept up to date in their section on "Message Accuracy." It's a pretty strong suggestion that they intend you to do a string search.
Also, according to this website, the Oracle Error structure also pretty strongly implies that they intend you to do a string search, because the data structure lacks anything else for you to get:
array(4) {
["code"]=>int(942)
["message"]=>string(40) "ORA-00942: table or view does not exist"
["offset"]=>int(14)
["sqltext"]=>string(32) "select * from non_existing_table"
}
This output reveals the following information:
The variable $erris an array with four elements.
The first element is accessible by the key ‘code’ and its value is number 942.
The second value is accessible by the key ‘message’ and the value is string “ORA-00942: table or view does not exist”.
The third value is accessible by the key ‘offset’, and its value is the number 14. This is the character before the name of the
non-existing table.
The fourth member is the problematic SQL message causing the error in the first place.
I agree with you; it would be great if there were a better way to get the constraint name you're violating, but string-matching seems to be the intended way.

Response message: Composite message or optional fields

We are working with a set of web services and we're looking for the best option to return errors to the web service's consumer. This is the current response:
Response
Some data about the server
Some data about the user
Some resulting data of executing the transaction
So, we need to return errors too. these are our options:
Composite message
we'll return two kinds of responses depending if the transaction was approved or had an error:
First:
type identifier (this message is serialized. so I need to know which kind of message I'm dealing with, to deserialize the last part)
Some data about the server
Some data about the user
Some resulting data of executing the transaction
Second:
type identifier (this message is serialized. so I need to know which kind of message I'm dealing with, to deserialize the last part)
Some data about the server
Some data about the user
The errors
Optional fields
the transaction data and error fields will be optional. if there's no errors I will know it was approved.
Some data about the server
Some data about the user
Some resulting data of executing the transaction
The errors
Which option is more appropriate?
This is discutable and more of a personal opinion than a best practice.
My personal favor is to use the Optional fields, because the error code is possible outcome of an operation. I would expect the client to always first check the (optional) error properties of the returned result before parsing the results. This allows to also return non-fatal errors and partial results together. Exclusive makes it so ... exclusive. Optional is more flexible.