Error creating task using Asana API - asana

we have been using the ASANA API about 4 month, but today we started get an error trying to create task in Asana:
5:15:48,208 ERROR [stderr] (pool-13-thread-1) Exception in thread "pool-13-thread-1" com.sun.jersey.api.client.ClientHandlerException: org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "num_hearts" (Class net.joelinn.asana.tasks.Task), not marked as ignorable
05:15:48,210 ERROR [stderr] (pool-13-thread-1) at [Source: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream#6eae04be; line: 1, column: 296] (through reference chain: net.joelinn.asana.tasks.Task["num_hearts"])
the error happens on client.createTask() call, see the code below:
protected void createProjectTasks(Project template, AsanaDetails asanaDetails, Long createdProjectId) {
try {
String asanaWorkspaceName = asanaDetails.getWorkspaceName();
Asana asana = new Asana(asanaDetails.getApiKey());
Tasks tasks = asana.projects().getTasks(template.id);
Workspace workspace = getWorkspace(asana, asanaWorkspaceName);
if (workspace == null) {
throw new AsanaException("Asana workspace with name " + asanaWorkspaceName + " is not found");
}
if (tasks == null) {
return;
}
Collections.reverse(tasks);
TasksClient client = asana.tasks();
for (Task task : tasks) {
TaskRequestBuilder taskRequestBuilder = new TaskRequestBuilder();
if (StringUtils.isNotBlank(task.name)) {
taskRequestBuilder.name(task.name);
taskRequestBuilder.completed(false);
taskRequestBuilder.addProject(createdProjectId);
taskRequestBuilder.workspace(workspace.id);
client.createTask(taskRequestBuilder);
}
}
} catch (ApiException e) {
throw new AsanaException(e.getMessage());
}
}
I checked the Task class, the are no field there annotated with "num_hearts", so, I'm a bit confused what got broken here, we haven't made any code changes for about a month...
and here is the api version:
<dependency>
<groupId>net.joelinn</groupId>
<artifactId>asana</artifactId>
<version>0.5.4</version>
</dependency>
Any thoughts?
Thanks in advance

We're happy to have released support in the API for hearts in both tasks and stories. These include the new fields, "hearted", "hearts", and "num_hearts". You can read more about this in our documentation.
Unfortunately, your client threw an error because it reached a new field (num_hearts) which it did not recognize. Since the client appears to be open source, you might want to send them a pull request to add support for the new hearts attributes. Alternatively, it may be worth to generalize the client so it does not throw an error when we add new fields in the future. In order to keep the API up-to-date with product developments, we will from time to time add fields and endpoints. You can rely on existing fields not going away, but it's bad to rely on no new fields being added.

Related

Not able to resolve HttpResponseException in .Net 5 Web Api

I am creating an Web Api using .Net Core 5. I want to implement error handling and return the response with the error. I found a article from Microsoft which suggested the following code. When I am implementing that code "HttpResponseException" is not found and I get a suggestion to install the nuget package for Microsoft.Aspnet.WebApi.Core. Once install it conflicting with the existing nuget package. I got this message "Microsoft.AspNet.WebApi.Core 5.2.8 was restored using .netFramework, Version=4.6.1..." As I said, I am trying to handling error as per best practices and my finding was to use Microsoft documentation in which it mentioned to use HttpResponseException (applicable scenario). If HttpResponseException is obsolete for .Net 5 what other option we have? Basically in the response when error occured, I want to send the customize ReasonPhrase.
public Product GetProduct(int id)
{
Product item = repository.Get(id);
if (item == null)
{
var resp = new HttpResponseMessage(HttpStatusCode.NotFound)
{
Content = new StringContent(string.Format("No product with ID = {0}", id)),
ReasonPhrase = "Product ID Not Found"
};
throw new HttpResponseException(resp);
}
return item;
}

The name does not exist in the current context. Shopping cart

I am following a guide to integrate PayPal into MVC 4. However, I have come upon this error "The name "Session" does not exist in the current context." & "The name "Response" does not exist in the current context."
https://www.asp.net/web-forms/overview/getting-started/getting-started-with-aspnet-45-web-forms/checkout-and-payment-with-paypal
protected void CheckoutBtn_Click(object sender, ImageClickEventArgs e)
{
using (ShoppingCart usersShoppingCart = new ShoppingCart())
{
Session["payment_amt"] = usersShoppingCart.GetTotal();
}
Response.Redirect("Checkout/CheckoutStart.aspx");
}
}
I have inputted the above code in my model which is linked to the checkout page.
Please enlighten me thanks. I am new to MVC.
It sounds like you're missing the System.Web namespace. Include it at the top of your class like so. If you then receive an error to the tune of 'namespace cannot be found', then you're missing the reference to System.Web.

breeze entitiesWithErrors not found but instead found entityErrors

The error object that is returned from breeze manager saveChanges() don't have the array entitiesWithErrors, but instead has the entityErrors array (perhaps is as it is on breeze.js version: 1.4.12, metadataVersion: 1.0.5)
The returned error object looks like...
Error {stack: "Error: Client side validation errors encountered", entityErrors: Array[6], message: "Client side validation errors encountered see the Errors collection on this object for more detail" entityErrors: Array[6] bla. bla..
Thus the code bellow will fail and I will need to refactor it if I am not able to work with entitiesWithErrors
function getErrorMessages(error) {
function getValidationMessages(err) {
try {
return err.entitiesWithErrors.map(function (entity) {
return entity.entityAspect.getValidationErrors().map(function (valError) {
return valError.errorMessage;
}).join('; <br/>');
}).join('; <br/>');
} catch (e) {
}
return 'validation error';
}
var msg = error.message;
if (msg.match(/validation error/i)) {
return getValidationMessages(error);
}
return msg;
}
This breaking change was made in Breeze version 1.4.0. From the release notes,
The description of client side validation errors caught during a save
before posting to the server has changed.
Client side validation errors caught during a save, but before posting
to the server, cause the save to fail and be routed to the fail
promise. The fail promise returns an error object that contains a
description of the errors. This description has changed.
Previously this error object contained an entitiesWithErrors property
that contained a list of all of the entities that had failed
validation. This property has now been replaced with the entityErrors
property. The entityErrors property returns a collection of
entityError objects as described above.
This change was made in order to retain consistency between save
failures that occurred on the server and those that failed before
posting to the server on the client.
To refactor your code, you simply do,
return error.entityErrors.map(function (entityError) {
return entityError.errorMessage;
})

Concurrency/ToDo Sample not working

I was trying out the ToDo sample and ran into an unhandled Excaption while trying out the Concurrency Handling.
The dataservice.js contains these lines in saveFailed(error) method:
if (detail && detail.ExceptionType.indexOf('OptimisticConcurrencyException') !== -1) {
// Concurrency error
reason =
"Another user, perhaps the server, may have deleted one or all of the todos.";
manager.rejectChanges(); // DEMO ONLY: discard all pending changes
}
The client never gets to this point due to an unhandled OptimisticConcurrencyException in:
[HttpPost]
public SaveResult SaveChanges(JObject saveBundle) {
return _contextProvider.SaveChanges(saveBundle);
}
I was trying to catch this and return the Exception which was kind of stupid as the Exception is not of type SaveResult. Is this a bug or am i missing an configuration somewhere?
Greets
Any server side errors should be returned to the promise.fail handler. i.e.
em.saveChanges().then(function(saveResult) {
// normal path
}).fail(function(error) {
// your concurrency exception message will be part of the error object.
});
Error on my side here... Clicking 'Continue' on the Exception Windows in VS the javascript handler is executed.

Getting the Id of an error in Elmah after calling .Raise()

I'm working on an MVC3 application and I'm using Elmah to handle my error logging. What I want in my application is to carry the Elmah Id onto the custom error page as I will provide a link which allows a user to specifically report it in the event that it is a repeat error (in their opinion).
Now, I've read similar questions on here and they suggest adding the following code (or similar) to the Global.asax.cs file:
void ErrorLog_Logged(object sender, ErrorLoggedEventArgs args)
{
string sessionId = Session.SessionID;
Session["ElmahId_" + sessionId] = args.Entry.Id;
}
This is what I'm using at the moment, with the SessionID allowing for added flexibility in making the Session stored object unique. However, this may still cause issues if more than one error occurs at (virtually) the same time.
Instead, I decided to work on my own HandleErrorAttribute that looks something like this:
public class ElmahHandleErrorAttribute : FilterAttribute, IExceptionFilter
{
public void OnException(ExceptionContext filterContext)
{
if (filterContext == null)
throw new ArgumentNullException("filterContext");
if (filterContext.IsChildAction && (!filterContext.ExceptionHandled
&& filterContext.HttpContext.IsCustomErrorEnabled))
{
Elmah.ErrorSignal.FromCurrentContext().Raise(filterContext.Exception);
// get error id here
string errorId = null;
string areaName = (String)filterContext.RouteData.Values["area"];
string controllerName = (String)filterContext.RouteData.Values["controller"];
string actionName = (String)filterContext.RouteData.Values["action"];
var model = new ErrorDetail
{
Area = areaName,
Controller = controllerName,
Action = actionName,
ErrorId = errorId,
Exception = filterContext.Exception
};
ViewResult result = new ViewResult
{
ViewName = "Error",,
ViewData = new ViewDataDictionary<ErrorDetail>(model),
TempData = filterContext.Controller.TempData
};
filterContext.Result = result;
filterContext.ExceptionHandled = true;
filterContext.HttpContext.Response.Clear();
filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
}
}
}
where ErrorDetail is a custom model which just has the public properties that are being set here as strings. This data can then be shown in the model for admin's at a quick glance and the errorId can be used to create the 'Report Error' link.
So my question is does anyone know of a way of getting the Id after the line
Elmah.ErrorSignal.FromCurrentContext().Raise(filterContext.Exception)
without using the Logged event in the global.asax.cs?
Any thoughts are much appreciated.
After reading Dupin's comments it seems logical that it isn't quite possible. I tried digging around the Elmah source code and came up with a couple of alternatives that might be worth sharing.
The obvious alternative is stick with my original option of using the Logged event:
void ErrorLog_Logged(object sender, ErrorLoggedEventArgs args)
{
string sessionId = Session.SessionID;
Session["ElmahId_" + sessionId] = args.Entry.Id;
}
For a more direct solution it is possible to manually log the error with the following:
string errorId = Elmah.ErrorLog.GetDefault(HttpContext.Current)
.Log(new Elmah.Error(filterContext.Exception));
However, using this approach won't hit your filters or mail module and so on.
After doing a bit of thinking and a little more searching, I came up with a new compromise. Still using the logged event but I've found a way to create a new unique key that can be passed to the view, by adding my own data to the exception.
string loggingKey = "ElmahId_" + Guid.NewGuid().ToString();
filterContext.Exception.Data.Add("LoggingKey", loggingKey);
This way I can pass the exception in my view model, which has this key value in the Data collection. The logged event would be changed to something like this:
void ErrorLog_Logged(object sender, ErrorLoggedEventArgs args)
{
string key = args.Entry.Error.Exception.Data["LoggingKey"].ToString();
Session[key] = args.Entry.Id;
}
Then in the view I get the key from the model to then pull the Id from the Session collection.
Maybe not very helpful but I suspect you can't get the error id at that point and you will need to use the logged event.
When you call
Elmah.ErrorSignal.FromCurrentContext().Raise(filterContext.Exception)
You're just raising the error. Depending on how you've configured ELMAH you might be logging the error or you might just send an email or a tweet.
There's no direct link between a raised error and an Id. That will only come with logging which, if you're feeling funny, you could be doing in multiple places and so creating multiple ids.
http://code.google.com/p/elmah/issues/detail?id=148#c3 is an identical request and a proposed patch on the Elmah project site
The solution above only works only if there is a Session object (website scenario). We needed it to work in an Azure WorkerRole, or a console / desktop app type setup. This solution will also work for web and save some session memory. There isn't a perfect solution, but one that worked for us to be able to log the error and retrieve the stored ID AND fire off an email is to:
Store the error using ErrorLog.Log(error) (see: Using ELMAH in a console application)
Raise the error skipping the logging (SQL or otherwise)
For the second part, we used the implementation of ElmahExtension given here: https://stackoverflow.com/a/2473580/476400
and REMOVED the following lines adding the logging:
(ErrorLog as IHttpModule).Init(httpApplication);
errorFilter.HookFiltering(ErrorLog); //removed!
The entire call from our client code looks like this:
ErrorLog errorLog = ErrorLog.GetDefault(null);
errorLog.ApplicationName = "YourAppName";
Error error = new Error(ex);
string errorResult = errorLog.Log(error);
Guid errorId = new Guid(errorResult);
ex.LogToElmah(); //this is just going to send the email
You might want to call that extention method something else, like RaiseToElmahNoStorage(), or something to indicate it is skipping the storage component.

Resources