Skip to content

Instantly share code, notes, and snippets.

@furey
Last active November 2, 2023 11:21
Show Gist options
  • Save furey/fcc246f30db9596617543f55ba5e175f to your computer and use it in GitHub Desktop.
Save furey/fcc246f30db9596617543f55ba5e175f to your computer and use it in GitHub Desktop.
In response to Taylor Otwell's tweet, "What are the worst parts of Laravel that drive you crazy?"

In response to

What are the worst parts of Laravel that drive you crazy?

https://twitter.com/taylorotwell/status/804485708136202240

Issue

Queued jobs often relate to specific model instances.

Obviously, depending on business requirements this is not always the case, but I find jobs generally perform some kind of action relating to a model. SerializesModels and all that.

Once a job is queued or failed, as the model context for that job is buried in the payload, it's difficult and expensive to query the jobs/failed_jobs tables for records that relate to the model the job was created for.

Also, and probably most pertinent to other developers, the reason why a job failed is not easily determined by looking at the failed_jobs table. Without prior planning, I need to inspect server/application logs for exception information as to why a job failed.

Example

In a project I recently worked on, a queued database job scrapes web resources (ScrapeResourceJob).

On job instantiation, a web resource model (Resource) is passed to it. Laravel stores this model by reference in the serialized, json encoded payload column of a new record in the jobs table.

When a ScrapeResourceJob fails, (pretty much) that same serialized, json encoded payload containing that model reference is stored in a new record in the failed_jobs table.

In this project, there were occasions when I need to check whether a Resource model:

  • had a queued ScrapeResourceJob (and if so, not queue another one)
  • had any failed ScrapeResourceJob (and if so, handle them appropriately)

I worked around this by executing a ->where('payload', 'LIKE', $gnarlyStringContainingClassNameAndId) query on the jobs/failed_jobs tables for the existance of relevant records, but, you know, soooo not Zonda™.

With regard to capturing the reason a failed job occurred, in this project I've wrapped my job handle() logic in a try/catch and after a determined number of attempts store the guilty exception, exploded into full class path and exception message, in a failed_scrapes table.

In another project I also store the full stack trace as a string. I find that having an easily visible breakdown of the fail-causing exception in a database record helps me action those fails, instead of the somewhat vague failed_jobs table Laravel currently provides.

Proposal

An easy way to query failed job related models would be awesome, but the nature of jobs being they can do whatever you want them to, with a model or multiple different models or collection of model/models or no models at all means I'm not quite sure of the best way to approach it.

With regard to the reason why a job failed, I believe storing fail-causing exception information would prove valuable to anyone trying to debug failed jobs.

Finally

Laravel is awesome – it's seriously changed my life.

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment