Bug Report Overview0:00
It works on my machine are five words that have ended friendships and ruined weekends. And in my case, it's added a lot of gray hair. But you know, it's one of those very common things that unfortunately we just have to deal with. So I received a bug report for my nightmare marked, and we need to sign in as a user. Now, thankfully, I have that information right here because why not? That's perfectly safe, isn't it?
because why not? That's perfectly safe, isn't it? So the bug that has been reported is, you know, users can come in, they can browse the shop, they can go to an item and they can add it to the card, and everything works fine until they get to proceed to check out. And whenever they try to check out, the tax is zero. Now that's an issue because if we don't collect tax, we have to report that
Now that's an issue because if we don't collect tax, we have to report that to the government and just don't want to go there. So this is an issue, but here we can see that it's working just fine. And you know, I'm in my development environment and of course it works on my machine. You know, this is the, the very dangerous parts about these types of issues because for the most part, they are invisible locally or,
Environment-Specific Failures1:17
dangerous parts about these types of issues because for the most part, they are invisible locally or, or at least in development because you can't catch it without actually simulating production. So what do you do, do, do you set up, you know, your development environment and then another production environment that you could then use to test? Ideally, yes, but sometimes that's not feasible.
that you could then use to test? Ideally, yes, but sometimes that's not feasible. But then, and, and I'm not gonna say most importantly because this really isn't the most important thing, but it erodes trust because, you know, we could say, well, we've tested this, we have tests to run and check all of these things. So yes, we tested it, yes, it works, but it works on my machine. So we have essentially the same application,
Production Caching Effects2:05
but it works on my machine. So we have essentially the same application, the same exact code, but two different results. And those results are dependent upon the environment. So that should give us a clue, it's an environment issue. So then we have to think, okay, what, what, what do we do to get from development to deployment or to production? And there's that whole deployment thing there, there are so many things that we do to deploy an application, but one of the most important things is to cache things,
so many things that we do to deploy an application, but one of the most important things is to cache things, you know, because if we take a look at, you know, our application, we have configs, there are a lot of files that are there, and so we want to cache those so that they just get combined into one file and it's much faster that way. The same is true for our routes and for our views. There are so many things that we want to cash
The same is true for our routes and for our views. There are so many things that we want to cash because it just makes our application much more performant in production. So, you know, maybe we start there, but we don't want to cache just everything. We want to take it step by step so that, you know, if we c the config and if we see that the problem is there, then we at least know that we need to focus on the config.
Reproducing with Config Cache3:19
and if we see that the problem is there, then we at least know that we need to focus on the config. But if the config is fine and we cache the routes, I don't know why the routes would do that. But if, if then we see that the issue is, is there, then you know it's probably an issue with the routes. So let's just do this one at a time. Let's start alphabetically. So we will, uh, config cache
Let's start alphabetically. So we will, uh, config cache and theoretically we should be able to go back to the browser, refresh this page, and hopefully the text will be zero. And it is, so it's an issue with the config. So then the question becomes, okay, it's an issue with the config. How do we find this? Now we could look at the code and, and that's fine, but this is also where having meticulous
Using Logs to Diagnose4:01
How do we find this? Now we could look at the code and, and that's fine, but this is also where having meticulous logs is very useful because if you are meticulous in your logging, then you can get a much better picture as to what is going on with the application in the environment that it's in, and then go from there. So, uh, I have logs and you know, we don't necessarily need these calculating cart totals.
and you know, we don't necessarily need these calculating cart totals. So let's get rid of that and let's focus on these two lines here because we are going to see two different results. This first line is before we cashed the config, we can see that the tax rate is 8%, the environment function results is 8%, and then a config value is no. Okay, well, let's not worry about the config value because that comes later, but then
Okay, well, let's not worry about the config value because that comes later, but then after we have cashed the config, we can see that the tax rate is no, that's a pretty big indicator that the environment function result is no, and our config value is still null. So it, it's an issue with environment really. So if we take a look at our controller, this gives us a much better idea of what we need to look for.
Fix: Move env to Config5:15
this gives us a much better idea of what we need to look for. Could be because it, it seems to indicate that we are using the environment function to get the tax rate value. And sure enough that that's what we are doing here. And, and that is essentially the crux of the problem. We are directly using or accessing the environment inside of our controller or inside of our services or things like that.
or accessing the environment inside of our controller or inside of our services or things like that. And that's not really good because whenever we cash our config and we try to access the environment variables, it's gonna return null as we have seen as my logging showed us. So what do we do in this case? Well, we would want to save this in our config and then we would want to use our config to get this value.
Well, we would want to save this in our config and then we would want to use our config to get this value. So I already have a config file. In fact, I already have everything that I need there. I have this tax rate and all I need to do is just uncommon that. So ideally what we would do is in our config, we would get the tax rate, we would get that from the environment, or we would have the default of 8% so that then
that from the environment, or we would have the default of 8% so that then inside of our controllers and throughout our application, we would use the config function so that we would get the shop tax rate instead of the environment. So there's one other place where we call environment to get the tax rate. And there it is right there.
call environment to get the tax rate. And there it is right there. So if we do that and if we clear out our config cache, let's cache our config again and back inside of the browser, we should be able to refresh this and we should see our tax. Now to be clear, this is not a bug, this is an actual part of Laravel and we can read this from the documentation. If you execute the config cache command
of Laravel and we can read this from the documentation. If you execute the config cache command during your deployment process, you should be sure that you are only calling the environment function from within your configuration files. Once the configuration has been cached, the dot e mv file will not be loaded. Therefore, the environment function will only return external system level environment variables. Now, you may have already known this, that's fine.
external system level environment variables. Now, you may have already known this, that's fine. There are many people that don't and they are going to run into this at one point in time problem, probably more than one point in time. And maybe I'm speaking from experience, maybe not. So when it comes to it works on my machine, you know, there is no magic bullet because there are so many
there is no magic bullet because there are so many different things that can go wrong. But for this particular issue, there are three things that you need to remember. First of all, the environment function belongs only in config files. Never use it in, uh, controllers or models or services or anywhere else within your application. Only use them inside of your config files.
or anywhere else within your application. Only use them inside of your config files. The second thing is to use the config function everywhere else because it reads from the cached configuration. And whenever you cache your config, the environment function is going to return null for anything that is not a, an actual system external environment variable. So use the environment function inside of your config files, use the config function to access those config settings.
So use the environment function inside of your config files, use the config function to access those config settings. But then third, and this is probably the most important thing, is before you deploy your application cash, cash your config, cash your routes, cash, your reviews, and then test your application. Because the very first thing that we do before we deploy our application is cache and caching, as we have seen, changes the behavior
before we deploy our application is cache and caching, as we have seen, changes the behavior of some things within our application. So don't use the environment function except in config files. Use the config function everywhere else within your application and cache before you deploy and test.
