[1.2.7] "No route found" when sending email from asynchronous job

382 views
Skip to first unread message

Julien Nauroy

unread,
Mar 4, 2014, 4:27:13 PM3/4/14
to play-fr...@googlegroups.com
Hi,

I'm having a problem when sending emails from an asynchronous job.

I have a shop-like application that sends welcome emails when a registered user adds a new client.
The email contains a link in the form @@{Admin.index()}
Until now, the email was sent straight away, and everything was going well.

I'm willing to move to sending the email using an asynchronous job running every few minutes. The idea of the job is the following:
@Every("1mn")
public class Welcome extends Job {
public void doJob() {
Client client = Client.find("...'").first();
notifiers.Mails.sendWelcomeEmail(client);
}
}

Now I have the following exception:
Error during job execution (jobs.Welcome)
No route found (In /app/views/mails/sendWelcomeEmail.html around line 24)
No route able to invoke action Admin.index with arguments {action=index, controller=admin} was found.
play.exceptions.NoRouteFoundException: No route found
at play.templates.BaseTemplate.throwException(BaseTemplate.java:82)
...



Do you have any idea what's happening, and why there is no problem when sending the email directly?


Best regards,
Julien Nauroy

Iván San José

unread,
Mar 5, 2014, 2:19:27 AM3/5/14
to play-fr...@googlegroups.com
Are you sure that in you e-mail view template you are calling only to
Admin.index() ? The error doesn't say that.
> --
> You received this message because you are subscribed to the Google Groups
> "play-framework" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to play-framewor...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.

Julien Nauroy

unread,
Mar 5, 2014, 2:37:28 AM3/5/14
to play-fr...@googlegroups.com
Just to double check, I've stripped the email template file down to only @@{Admin.index()} and now the error is the same, just says "around line 1":

No route found (In /app/views/Mails/sendWelcomeEmail.html around line 1)
No route able to invoke action Admin.index with arguments {action=index, controller=admin} was found.

play.exceptions.NoRouteFoundException: No route found
        at play.templates.BaseTemplate.throwException(BaseTemplate.java:82)
        at play.templates.GroovyTemplate.internalRender(GroovyTemplate.java:257)
        at play.templates.Template.render(Template.java:26)
        at play.templates.GroovyTemplate.render(GroovyTemplate.java:202)
        at play.mvc.Mailer.send(Mailer.java:223)
        at notifiers.Mails.sendUserWelcomeEmail(Mails.java:46)
        at jobs.ClientZone.doJob(ClientZone.java:33)
        at play.jobs.Job.doJobWithResult(Job.java:50)
        at play.jobs.Job.call(Job.java:146)
        at Invocation.Job(Play!)



You received this message because you are subscribed to a topic in the Google Groups "play-framework" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/play-framework/TjRe2-K3c6w/unsubscribe.
To unsubscribe from this group and all its topics, send an email to play-framewor...@googlegroups.com.

Iván San José

unread,
Mar 5, 2014, 2:58:50 AM3/5/14
to play-fr...@googlegroups.com
Probably Play! is not being able to resolve the baseUrl because the
Job is running in another thread and it can't have access to the
Http.Request context. Try to set
application.baseUrl=http://localhost:9000/ in you application.conf
file.

Julien Nauroy

unread,
Mar 5, 2014, 3:33:06 AM3/5/14
to play-fr...@googlegroups.com
Thanks for your help.
Unfortunately, it still doesn't work after adding application.baseUrl.
Is there an alternative syntax I can try to see if it works better? Or a way to list the currently-loaded routes?

Grzegorz Slowikowski

unread,
Mar 5, 2014, 3:34:50 AM3/5/14
to play-framework
Grzegorz Slowikowski

Iván San José

unread,
Mar 5, 2014, 3:44:18 AM3/5/14
to play-fr...@googlegroups.com
Yes, you can use play.mvc.Router.reverse method, but would be the same
that the @@{} tag makes under the hood.

Mariusz Nosinski

unread,
Mar 5, 2014, 1:41:13 PM3/5/14
to play-fr...@googlegroups.com
Of course you have controller "Admin" with static method "index()" without parameters, and entry in "routes.conf" pointed to this method?

can you show us this line from routes?

Julien Nauroy

unread,
Mar 6, 2014, 1:57:00 AM3/6/14
to play-fr...@googlegroups.com
Yes, the route exists. This is even the default route. Here's my first lines in the routes file:

# Home page
GET     /                                       Admin.index(format:'html')

I've been sending the exact same email for some time so I'm sure the routes called in the email are OK.

Strange enough, if I replace "@Every("1mn")" with "@OnApplicationStart" I have no error and the email is sent properly.
I've tried displaying the number of routes when doJob starts (play.mvc.Router.routes.size()) and get the same number in both tests.

I'm trying to create a new project with minimal functionality and still able to reproduce the problem.
Maybe I'll be able to come up with more information or a reproducible example.





Seb

unread,
Mar 6, 2014, 3:09:20 AM3/6/14
to play-fr...@googlegroups.com
Hi

I guess i encountered the same problem some years ago but can't remember what exactly was my problem.

But, as a workaround in my case, in my Mails class for every mail I pass an applicationUrl argument that is constructed by getting the application.baseUrl parameter.

I am also sending mails in a job so it may be the same bug as yours that carry me to this solution

Regards
Seb

Julien Nauroy

unread,
Mar 6, 2014, 4:10:01 PM3/6/14
to play-fr...@googlegroups.com
Thanks for all your suggestions.
I think I get it now. When trying to create the route URL by myself, I investigated into the sources, specifically Router.reverse.
In mvc/Router.java, line 461 says:
 if (!(Http.Request.current() == null ? "" : Http.Request.current().format).equals(route.staticArgs.get("format"))) {

In short, it checks if the current request's format corresponds to the route's format and if it doesn't, considers the route is not eligible.
In my case, the current request is null since it's an asynchronous call, and the format is set to "html" because I set it statically.
(On a side note, I've done so because some browser or something tried to negociate other formats than HTML, and it generated exceptions because proper template files could not be found, so I forced output to be HTML)


So it looks like an asynchronous job is not able to generate a route with a static format set.
For now,I've changed this line to:
if (Http.Request.current() != null && !Http.Request.current().format.equals(route.staticArgs.get("format"))) {
so that the check if performed only if there is a request.

I'm not sure if it's a good solution in the general case and thus if it should be proposed as a patch.
What do you think?


Reply all
Reply to author
Forward
0 new messages