Description of problem: With the asynchronous push implementation, if a push fails because of a permission check (eg locale not enabled on the server), the client error message is extremely generic ("Failed while pushing document translations"), even if exceptions are enabled with Maven's -e option. By looking at the server log, I discovered that the actual cause was Locale <locale> is not allowed for project <project> and version <version>. Please contact project maintainer. We should extend the async API so that the true error message can be propagated to the client, as it is with the older, synchronous version of push. Version-Release number of selected component (if applicable): Server 2.1.4-SNAPSHOT (20130125-0019) Client 2.0.1 How reproducible: 100% Steps to Reproduce: 1. Attempt to push to a locale which has not been enabled for the project 2. Observe error message Actual results: Failed while pushing document translations: [] Expected results: Failed while pushing document translations: Locale <locale> is not allowed for project <project> and version <version>. Please contact project maintainer. Additional info: 2013-01-25 16:12:36,034 ERROR [org.zanata.process.AsynchronousExecutor] (DefaultQuartzScheduler_Worker-7) Exception with long running process: Locale <locale> is not allowed for project <project> and version <version>. Please contact project maintainer. 2013-01-25 16:12:36,034 ERROR [org.zanata.rest.service.AsynchronousProcessResourceService] (DefaultQuartzScheduler_Worker-7) Error pushing translations org.zanata.exception.ZanataServiceException: Locale <locale> is not allowed for project <project> and version <version>. Please contact project maintainer. at org.zanata.service.impl.LocaleServiceImpl.validateLocaleByProjectIteration(LocaleServiceImpl.java:196) at org.zanata.service.impl.LocaleServiceImpl_$$_javassist_seam_20.validateLocaleByProjectIteration(LocaleServiceImpl_$$_javassist_seam_20.java) at org.zanata.service.impl.TranslationServiceImpl.translateAllInDoc(TranslationServiceImpl.java:445) at org.zanata.service.impl.TranslationServiceImpl.translateAllInDoc(TranslationServiceImpl.java:411) at org.zanata.service.impl.TranslationServiceImpl_$$_javassist_seam_57.translateAllInDoc(TranslationServiceImpl_$$_javassist_seam_57.java) at org.zanata.rest.service.AsynchronousProcessResourceService$3.run(AsynchronousProcessResourceService.java:267) at org.zanata.rest.service.AsynchronousProcessResourceService$3.run(AsynchronousProcessResourceService.java:253) at org.zanata.process.AsynchronousExecutor.runAsynchronously(AsynchronousExecutor.java:61) at org.zanata.process.AsynchronousExecutor_$$_javassist_seam_56.runAsynchronously(AsynchronousExecutor_$$_javassist_seam_56.java) (NB: I trimmed all non-zanata lines in the stack trace.)
Error messages produced by the server where being overwritten by a possibly empty set. Fixed in 2.1.x and 2.2.x See: https://github.com/zanata/zanata/commit/c199df67738e5418091bd1224f0fa7fa83d9868a
Tested with Zanata version 2.1.5-SNAPSHOT (20130221-0020), maven client 2.0.2-SNAPSHOT The actual error message become: [WARNING] Authentication error: Unable to respond to any of these challenges: {} [ERROR] Operation failed. To retry from the last document, please add the option: -Dzanata.fromDoc="ibus-chewing" [INFO] ------------------------------------------------------------------------ [INFO] BUILD FAILURE [INFO] ------------------------------------------------------------------------ [INFO] Total time: 8.723s [INFO] Finished at: Thu Feb 21 14:39:54 EST 2013 [INFO] Final Memory: 12M/123M [INFO] ------------------------------------------------------------------------ [ERROR] Failed to execute goal org.zanata:zanata-maven-plugin:2.0.2-SNAPSHOT:push (default-cli) on project null: Zanata mojo exception: Error status 401 Unauthorized returned -> [Help 1] Reassigned
The error is being handled and the message is actually correct although it's not very precise. We need to do a general review of how we are handling error messages in the rest clients as it should be done in a uniform way accross the whole Rest API. We may need to map some general exceptions in the Rest API that can be subclassed and used by the business logic components, and then transformed into Http error codes by the REST components.
This is a 6 month stale bug (of 3 releases ago). This should be verified as working|notworking, https://bugzilla.redhat.com/show_bug.cgi?id=915529 is the "give me nicer messages" issue.
Do you mean that error messages should be identical between WebUI and client except some cosmetic change? For example, if a user push it.po with client and fail because he/she has not join it langage team. The error message shown in client should be like: Cannot push it.po because you are not yet a member of language team it. And if the user upload it.po with WebUI, the error message should be almost the same: Cannot upload it.po because you are not yet a member of language team it.
I mean if the real error message (as seen in server.log) is "Locale <locale> is not allowed for project <project> and version <version>." then this message should be returned to the user. The error message should not change into something generic like "Unable to respond to any of these challenges". This isn't about error codes: the response code 401 is perfectly correct in this case; it's about also returning an entity which contains the correct error message, and then having the client display the error message.
Tested with Zanata version 3.0.4-SNAPSHOT (20130923-0021), zanata-cli-3.1.2 Pushing it when you are not in language team it with: zanata-cli -B -e push -s . -t . --push-type trans --locales it 1) Client: == ][WARN] Authentication error: Unable to respond to any of these challenges: {} [ERROR] Execution failed: java.lang.RuntimeException: Operation failed. To retry from the last document, please set the following option(s): --from-doc "tar" . at org.zanata.client.commands.push.PushCommand.pushCurrentModule(PushCommand.java:459) at org.zanata.client.commands.push.PushCommand.run(PushCommand.java:207) at org.zanata.client.commands.ArgsUtil.runCommand(ArgsUtil.java:56) at org.zanata.client.ZanataClient.processArgs(ZanataClient.java:164) at org.zanata.client.ZanataClient.main(ZanataClient.java:90) Caused by: org.jboss.resteasy.client.ClientResponseFailure: Error status 401 Unauthorized returned at org.jboss.resteasy.client.core.BaseClientResponse.createResponseFailure(BaseClientResponse.java:558) at org.jboss.resteasy.client.core.BaseClientResponse.createResponseFailure(BaseClientResponse.java:549) at org.jboss.resteasy.client.core.BaseClientResponse.checkFailureStatus(BaseClientResponse.java:543) at org.jboss.resteasy.client.core.extractors.BodyEntityExtractor.extractEntity(BodyEntityExtractor.java:37) at org.jboss.resteasy.client.core.ClientInvoker.invoke(ClientInvoker.java:125) at org.jboss.resteasy.client.core.ClientProxy.invoke(ClientProxy.java:88) at com.sun.proxy.$Proxy75.startTranslatedDocCreationOrUpdate(Unknown Source) at org.zanata.client.commands.push.PushCommand.pushTargetDocToServer(PushCommand.java:638) at org.zanata.client.commands.push.PushCommand.access$100(PushCommand.java:52) at org.zanata.client.commands.push.PushCommand$1.visit(PushCommand.java:435) at org.zanata.client.commands.push.AbstractGettextPushStrategy.visitTranslationResources(AbstractGettextPushStrategy.java:104) at org.zanata.client.commands.push.PushCommand.pushCurrentModule(PushCommand.java:428) ... 4 more 2) Server shows: Actual: Nothing Expected: Pushing failed (reason) REASSIGNED
We need to revisit the all the REST end points to see how we handle the exceptions. Setting this medium priority.
For example, when invoke client with following command: z -B push --push-type trans --merge-type import There are two(maybe more) possible permission failure: user is not part of the language team user don't have permission to do merge type import operation In the past what we get back is just a 401 with no body in response. Now we can tell what exactly go wrong: when user is not a member for the locale [ERROR] Execution failed: * Error Message: PUT http://localhost:8080/zanata/rest/async/projects/p/jasper/iterations/i/1/r/MessageResources/translations/de?ext=comment&merge=import&assignCreditToUploader=false returned a response status of 401 Unauthorized; * Response From Server: Failed to obtain permission(modify-translation) with following facts([Locale(id=de, name=German), Project(name=jasper, slug=jasper, status=ACTIVE)])] when user is a translator but not project maintainer (no permission to do merge import) [ERROR] Execution failed: Failed while pushing document translations: [Failed to obtain permission(import-translation) with following facts([Project version(slug=1, status=ACTIVE)])]
server PR: https://github.com/zanata/zanata-server/pull/787 client PR:https://github.com/zanata/zanata-client/pull/60
I suggest that return code should be 403 (Forbidden) as it indicate that user is not allow to do it. 401 is for user failed to authenticate (wrong username or API key).
(In reply to Ding-Yi Chen from comment #11) > I suggest that return code should be 403 (Forbidden) as it indicate that > user is not allow to do it. > > 401 is for user failed to authenticate (wrong username or API key). Good point. For reference http://stackoverflow.com/a/6937030/345718
VERIFIED with Zanata 3.7.0-SNAPSHOT (git-jenkins-zanata-server-github-pull-requests-3368)