I've got an IoT Hub, message routing feeding two event hubs in one namespace, and two functions trying to read from those two event hubs. Sometimes only one function gets called, sometimes neither. So I'm trying to learn how to debug these issues. In storage explorer I found insights-logs-routes, and I'm wondering is this significant:
"operationName": "undefinedRouteEvaluation",
"category": "Routes",
"level": "Information",
"properties": "{\"deviceId\":\"EAxxx\",\"endpointName\":null,\"messageId\":null,\"details\":null,\"routeName\":\"checkinroute\",\"statusCode\":null}",
Does the "undefined" part of that mean that I'm missing something? Google can't find "undefinedRouteEvaluation" anywhere.
The messages definitely get sent from the device to the IoTHub, the vscode extension can see them. And half of the routing works ... sometimes.
I've also seen these errors in my logs and also cannot find anything in the webs about them, and I've also had issues with routes resolution.
In my case it turned out that I was defining routes on message body $body.SomeProperty='some string value' but this 'style' is supported only when the JSON document coming from the device has additional information about encoding. If this information is missing the route will not be resolved and the messages will flow the the fallback route.
To correct the problem I had to define route query on applicationProperties part of the message (in my case all the properties from the message body were passed to the applicationProperties dictionary automagically). The query had to become SomeProperty='some string value'.
Now it routes work fine and stably.
Related
Modifying Piranha for 'headless' scenario: I separated the api into its own REST API, and the MVC into its own UI that calls the REST API. Mostly it works well, but now an obstacle. My REST API serializes the result from the Piranha api, and my MVC web deserializes it into a Piranha StandardPage type. This works for all fields except Media, which is always null. Using newtonsoft.Json.
The Media property is defined in Piranha.Extend.Fields.MediaFieldBase with internal set, which explains why I can't deserialize into it. So I added a [JsonProperty] attribute to the Media property. Once I did this, then the Media field was correctly deserialized by the MVC, and images appeared.
But then I found this broke something else: in the manager, when I try to save a page with a Hero image, the Save buttons spins, stops as though it succeeded, but the toast never appears saying success. I set Debug logging for Microsoft.AspNetCore.Mvc.Infrastructure, and see there's a model state error when this happens:
dbug: Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker[2]
Executed controller factory for controller Piranha.JA.Manager.Controllers.PageApiController (Piranha.JA.Manager)
dbug: Microsoft.AspNetCore.Mvc.Infrastructure.ModelStateInvalidFilter[1]
The request has model state errors, returning an error response.
dbug: Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker[3]
Request was short circuited at action filter 'Microsoft.AspNetCore.Mvc.Infrastructure.ModelStateInvalidFilter'.
I can debug into the PageApiController for most operations, but when Save executes none of the breakpoints are hit.
I also tried just removing the internal accessor from set (and removing [JsonProperty]) and got the same behavior: can deserialize Media ok but trying to save page with a Hero from manager gives model state error.
Would love to write up some documentation on how to go headless if we can solve this.
We've been debugging this one for a few days, can anyone help?
In the branch I pushed I actually changed the accessor to public, so you shouldn’t need the additional attribute. This is also merged to master and will be released in 8.3.
Regards
I posted this on the Piranha CMS github and one of its authors, Hakan Edling, answered in just a few hours:
"The root issue is that when a new item is selected in the manager in the media picker, the media model that is assigned contains a formatted string size "xxx kb". When ASP.NET tries to deserialize this into a long it fails.
So changing the following line in the .vue components for the media-based fields:
this.model.media = media;
to
this.model.media = {
id: media.id,
folderId: media.folderId,
type: media.type,
filename: media.filename,
contentType: media.contentType,
publicUrl: media.publicUrl,
};
Resolves the serialization error in the manager when the Media property is public.. I'll push this fix to a new branch so you can test it."
And soon after,
"Please test with the branch https://github.com/PiranhaCMS/piranha.core/tree/features/make-mediafield-media-public"
I still must add the [JsonProperty] attribute to the Media field in MediaFieldBase class, so my deserializer can access the internal set method. Hakan's fix makes it so this attribute doesn't break the manager.
Thank you for your quick response Hakan, you rock!
I've built a custom query server for a custom query language.
I've tried to create a design document with views map/reduce.
In those map/reduce functions (most importantly in the map function) I want to be able to reference library code.
I can see there is a lib node that can be added to the design document.
I am expecting the custom query server to receive add_lib message from CouchDB, but I have never seen this yet.
http://docs.couchdb.org/en/stable/query-server/protocol.html#add-lib
add_fun messages fail for code that depends on the library in the query server because the add_lib message has not yet been received in advance.
"The Query Server should parse, compile, and evaluate the function it
receives to make it callable later."
http://docs.couchdb.org/en/stable/query-server/protocol.html#add-fun
Since add_fun fails, this means that I am unable to save the design document.
I have viewed the following pages but I still no success:
How do I add the moment.js library to Cloudant NoSQL Design Doc on Bluemix
How do I DRY up my CouchDB views?
https://www.oreilly.com/library/view/couchdb-the-definitive/9780596158156/ch05.html
I'm doing something wrong or made a mistake it seems, your help is greatly appreciated.
The following website has the correct way to put a lib into a view.
https://caolan.org/posts/commonjs_modules_in_couchdb.html
Here's a new example for a fictitious language which is based on the working one.
{
"_id": "_design/example",
"language": "customlang",
"views": {
"lib": {
"math": "pi = 3.14"
},
"map_everything_to_pi": {
"map": "imports math; pi"
}
}
}
My problem arose because I could not save the design document when I had code in the map function that depended on the library.
By adjusting the map function to not depend on the library, I have now been able to save the document and upon querying the view, I witnessed the add_lib message get sent to the query server.
In CouchhDB 2.2.0 add_lib is sent when the view is queried, but not immediately on saving the design document where add_fun is called. In my view add_lib should be called before for each lib before CouchDB sends the add_fun messages.
This fact makes it impossible for add_fun to evaluate / precompile the code since the library is not yet known. add_lib must succeed in order for the design document to save, so it is impossible to save the design document.
I probably need to raise a bug tracker issue.
Suppose I ask a question to an criminal register: http://server/demographics/party/{partyId} and that person is not known on that system.
Is that an error? Isn't it a good thing?
When returning 404, it is an error code, Restlet has implemented it as a specific URL cannot be resolved to a route to a server-resource (a handling class), an erroneous situation.
In my opinion, if a system understands a call, and is able to process it without errors, it should return 200 (HTTP-ok), and it should return the information: "We don't know this person".
What is the best thing to do?
There's nothing wrong in returning a 404 status code. It simply means "you asked for a resource, and it doesn't exist". If it did return 200, it would have to somehow return an additional status code telling you that everything went fine, but the resource couldn't be found. That's unnecessary, because 404 already means exactly that.
A status 500 is normally returned to mean "something went wrong, I can't tell you if the resource exists or not". Now if you returned a 404 to mean that, this would be a mistake.
Whether it's a good thing or not is not doesn't have anything to do with HTTP or REST. And BTW, if the register was a file containing the survivors of a disaster, you would probably find it bad to not find the person you looked for, unless maybe if the person is your mother in law, unless you actually love your mother in law. (this is meant as a joke, for those who don't find it obvious).
A web service could be implemented in a way that produces either kind of response.
If it is being implemented in a way that is truer to HTTP/Rest, then '404 not found' would be the appropriate response for not finding something. This is what the 404 status is for.
It may help to think of your request as saying 'I assume this record exists, and I want to see it', and the 404 response as saying 'You are in error that record does not exist'.
If this URL is going to be used by code (rather than be displayed in a browser), then if you don't make a distinction in the response status then you will have to add extra information to the response body to make the difference obvious.
If this URL is going to be displayed to a user in a browser, then the server is still able to display content in the response body for a 404.
Please read: http://archive.oreilly.com/pub/post/restful_error_handling.html#__federated=1
Quoting:
Conclusion:
Human Readable Error Messages: Part of the major appeal of REST based web services is that you can open any browser, type in the right URL, and see an immediate response -- no special tools needed. However, HTTP error codes do not always provide enough information. For example, if we take option 1 above, and request and invalid book ID, we get back a 404 Error Code. From the developer perspective, have we actually typed in the wrong host name, or an invalid book ID? It's not immediately clear. In Option 3 (DAS), we get back a blank page with no information. To view the actual error code, you need to run a network sniffer, or point your browser through a proxy. For all these reasons, I think Option 4 has a lot to offer. It significantly lowers the barrier for new developers, and enables all information related to a web service to be directly viewable within a web browser.
Application Specific Errors: Option 1 has the disadvantage of not being directly viewable within a browser. It also has the additional disadvantage of mapping all HTTP error codes to application specific error codes. HTTP status codes are specific to document retrieval and posting, and these may not map directly to your application domain. For example, one of the DAS error codes relates to invalid genomic coordinates (sequence coordinate is out of bounds/invalid). What HTTP error code would we map to in this case?
Machine Readable Error Codes: As a third criteria, error codes should be easily readable by other applications. For example, the XooMLe application returns back only human readable error messages, e.g. "Invalid Google API key supplied". An application parsing a XooMLe response would have to search for this specific error message, and this can be notoriously brittle -- for example, the XooMLe server might simply change the message to "Invalid Key Supplied". Error codes, such as those provided by DAS are important for programmatic control, and easy creation of exceptions. For example, if XooMLe returned a 1001 error code, a client application could do a quick lookup and immediately throw an InvalidKeyException.
Based on these three criteria, here's my vote for best error handling option:
Use HTTP Status Codes for problems specifically related to HTTP, and not specifically related to your web service.
When an error occurs, always return an XML document detailing the error.
Make sure the XML error document contains both an error code, and a human readable error message. For example:
1001
Invalid Google API key supplied
By following these three simple practices, you can make it significantly easier for others to interface with your service, and react when things go wrong. New developers can easily see valid and invalid requests via a simple web browser, and programs can easily (and more robustly) extract error codes and act appropriately.
The Amazon.com web services API follows the approach of returned XML document can specify an ErrorMsg element.
XooMLe also follows this approach. (XooMLe provides a RESTful API wrapper to the existing SOAP based Google API).
Another approach is by DAS ( Distributed Annotation System) which always returns 200 if there was no HTTP-error and has error information in the HTTP-header, which is less favorable, because it is not human readable, as a browser does not display the HTTP-header.
We are designing a RESTful API to return collections of documents. Our initial implementation uses HTTP status codes to indicate if a request could not be fulfilled. This seems to be a widely accepted best practice (see for example here).
We recently ran into an issue where a user was pulling 1000 documents. One of the document retrievals failed, and thus we returned an HTTP 500 status code.
An alternative would be to return an HTTP 200 status code with the payload having the 999 documents that we were able to retrieve, and then an error collection indicating the one that failed.
Is this alternative approach a violation of RESTful principles? How should this situation be handled? Are there any options besides these two approaches?
Yes, I think it is perfectly acceptable as long as you document that the data that you are returning, can contain an "error" collection. This means that whatever semantic media-type you are using to describe this collection of documents, should have documentation that describes what the collection of documents should look like, and what the error collection should look like. The client can then decide what to do with this information.
For example, if you are returning this as JSON (just an example), you may have a media type like application/json+documents or something, which could look like this:
{ data : {
documents: [ ... ], //document objects
errors: [ ... ] //error objects
}
You would then have documentation that describes what the documents look like, and what the errors look like. In truly RESTful API's it is the media-types that are documented and not the calls, because in a truly RESTful API there is only one endpoint, and everything else is "discovered" via that initial endpoint, in conjunction with semantic media-types. So as long as you document that errors are possible, and you describe the format that the errors will be delivered, you should be alright.
This is also isn't an "exceptional" condition since it seems to be in your case that it is foreseeable that a client may not be able to retrieve all documents. Hence it is alright to inform the client of that fact.
There is a line that you sometimes have to cross in a unique situation like this: involving the user.
It's not unreasonable to notify the user that the payload is too large, and return an internal server error.
Rails 3.0.10 and activemerchant gem 1.29.3
My app works fine in sandbox, but transactions in production mode are failing with "Security header is not valid", "ErrorCode"=>"10002"
We initiated a support request with paypal, after reviewing all the configuration parameters a million times and they feel we're hitting an incorrect endpoint. They've asked for a full trace for the transaction, including headers, etc, so I'm trying to figure out how to do that. I found this article
which suggested adding this to the config block
ActiveMerchant::Billing::PaypalGateway.wiredump_device = File.new(File.join([Rails.root, "log", "paypal.log"]), "a")
But that just results in an empty log; nothing gets dumped to it.
So, how can I obtain this info from the GATEWAY object, if possible? Here's the production config, the format of which is identical to what's used in staging env.
::GATEWAY = ActiveMerchant::Billing::PaypalGateway(
:login => 'me_api1.blah...',
:password => 'string...',
:signature => 'longer string...'
)
Thanks.
Needed to add the additional line as follows:
ActiveMerchant::Billing::PaypalGateway.wiredump_device.sync = true
Within the same config block in the environment
Somewhere in the class library you're using there should be a function to output this for you (if it's a well built library, that is.)
Even without that, though, you should be able to look in that PaypalGateway function to see where/how it's setting the endpoint. It's either hard-coding the value or it'll be setting different endpoints based on some sandbox option you have configured somewhere else in the class.
It's hard to tell you more than that without getting a look a the actual class library you're using, but I can concur that it must be either incorrect credentials or an incorrect endpoint. I've never once seen that security header error when it wasn't simply invalid credentials, which means either your values are incorrect or you're hitting the wrong endpoint.
If you want to post that whole function (or maybe even the whole library as the endpoint could be getting set from some other function) I can take a look and find the problem for you.