Becoming a Reliable Developer

2021. 4. 20.

Becoming a Reliable Developer
image by Lukas Bieri

When you're a working professional, your attitude towards work naturally develops, much like a character. The same applies to developers. Being a junior doesn't mean having a bad attitude, nor does experience guarantee a good one. Like coding skills, attitude can be improved. Less experienced individuals often exhibit poor attitudes simply due to lack of knowledge. It's often said that the longer one has worked, the harder it is to change these established attitudes. Unfortunately, this broad, abstract concept of "attitude" is sometimes unfairly judged based on a single aspect or incident. I believe a crucial aspect of this attitude clearly emerges when problems arise during work.

Everyone Encounters Problems

Some people manage to handle any task assigned to them somehow, while others consistently run into problems that halt progress. Many factors contribute to this difference, and even the same person can vary from time to time. Even high performers can face difficulties sometimes. It might feel like luck, but unfortunately, there are individuals for whom things consistently don't go smoothly and problems always seem to arise. How they handle such negative situations reflects their specific attitude. The important point here is that the problem itself isn't the core issue. Naturally, not every task can be successful. Excelling at any given task doesn't mean achieving perfect success every time. It's great if the expected positive outcome is achieved, but if a problem leads to failure, one must fail correctly. There must be clear, narrowed-down reasons why it couldn't work, the process leading to that conclusion must be sufficiently persuasive, and ideally, alternative solutions should be proposed. Otherwise, someone else ultimately has to figure out the alternatives. Typically, those who frequently suggest alternatives, regardless of whether it's their issue or someone else's, tend to receive positive evaluations.

The Persuasiveness of Failure

What's perceived as an attitude problem isn't the failure itself, but how one responds to and resolves the problematic situation. Work tasks can exist in various states beyond just 'complete' or 'incomplete'. Transitioning to a negative state requires a clearer justification. To conclude something is a failure, you need to determine at what stage and after doing how much you can decide it's a failure or impossible. While there's certainly a "vibe that comes from experience" based on years worked, I believe this is separate from the depth of investigation. Even those at a lower level can thoroughly examine and narrow down a problem. Isn't skill built through the process of courageously approaching and solving the unknown? Of course, repeatedly doing what you know also builds insight, but learning something new seems to offer a greater volume of learning. And that makes it more interesting.

The Weight of a Question

A poor attitude ultimately manifests as prematurely stopping work or seeking help when a problem arises. This isn't to say asking questions or getting help is wrong. There's a significant difference between a question asked after sufficient experimentation and investigation, and one asked without such effort. Someone who has delved deeply enough into a problem to ask a question will ask clearly, providing sufficient information for the answerer, leading to a clear response. They quickly grasp the answer with a brief explanation, saying "Ah!". Otherwise, the person answering doesn't know where to begin, and conversely, the answerer ends up having more questions. This is an area where new employees often get reprimanded :) Asking too soon is a problem, but so is not asking when you should. It's difficult. I've been scolded many times myself.

All of this is often lumped together as "problem-solving ability." It becomes much more noticeable in negative situations.

Case Study: Mr. A

Let me share an example based on my actual experience. A new major update for the framework used in our project was released, requiring migration. This task was assigned to a colleague, let's call him A. After about a day of work, he suddenly reported that he couldn't proceed any further. When asked why, he explained that he followed the migration guide, encountered an unknown error, searched GitHub issues, found developers experiencing similar errors, tried the suggested solutions there, but they didn't work. Therefore, he concluded he couldn't continue the task.

A problem occurred, he searched for solutions, but found none that worked. However, at this stage, nothing is clear. The cause of the problem isn't clear, nor has it been narrowed down. He doesn't know what the error message means, and the only action taken was searching. This might seem like an extreme example, but it actually happened to me. (Sorry for using this case without permission, A). So, I outlined the things he should have done before reporting that it couldn't be done.

1. Direct Inquiry

If it were a blatant bug, there might genuinely be nothing one could do. In that case, you'd need to ask the framework developers or the community directly. I asked if he had posted a question on GitHub issues; he hadn't. This itself is a problem. If you genuinely want to solve it but absolutely cannot find the cause, you should ask via GitHub issues, the maintainer's Twitter account, or email. However, in his current state, asking the question itself would be an imposition. It's no different from saying, "I don't know, please figure it out for me." All he could do was present the error message. Questions like this greatly burden open-source maintainers. You need to narrow down and clarify the problem to ask core questions and provide necessary information. This increases the likelihood of getting an accurate answer quickly.

2. Problem Identification

First, the meaning of the error message needs to be clearly understood. While immediately copying parts of the error message into a search bar might sometimes help, if you don't find the answer you need, you must understand the error message itself. After analyzing the error message, it turned out to be a compatibility issue with a dependency called XX, which the framework uses. This dependency wasn't directly used by our service; it was a dependency of a framework plugin.

3. Narrowing Down the Problem

The suspicion was that a dependency used indirectly through the framework, via a plugin, was causing the issue. Since we weren't using any particularly special features of the framework, we judged it unlikely to be a bug or problem with the framework itself. It would likely work correctly in most situations; they released and promoted it because it worked, right?

Then, the next step is clear: strip down to the minimum code and configuration required to use the framework and check if the problem persists. If the error still occurs even with the bare minimum, the problem must lie outside the configuration. It could be a Node.js version issue or an NPM cache problem. At this point, it could indeed be a framework bug after all.

Fortunately, the basic setup worked fine. Now, to narrow down the problem, incrementally add back meaningful units of configuration and service code, rebuilding each time to pinpoint where the issue occurs. If you're lucky, you'll find it quickly; if not... it will take effort.

In this case, the error message initially pointed towards a framework plugin. So, we removed all plugins from the configuration and added them back one by one, rebuilding each time. Thankfully, we identified the plugin causing the problem. If simply adjusting plugin settings hadn't isolated the issue, we would have suspected a specific feature or API used in the service code and incrementally added back parts of the service code to find the culprit.

4. Reviewing Solutions

Once a specific plugin was identified as the problem, the first potential solution is to find a replacement for the plugin. There might be other plugins addressing the same problem. The problematic plugin was one that generated favicons. Fortunately, it had very little entanglement with the service's code. Thus, evaluating a replacement was relatively easy. If the problematic plugin were used directly via its API in the service code, replacing it could be difficult depending on the amount of code involved, right?

This case was fortunate in that regard. If it hadn't been, the next step would have been to narrow the problem down further to identify which specific API was causing the issue. You find the problematic part by starting with minimal service code and incrementally adding back meaningful units of service code. Once the causative API is found, you can search more specifically for shared issues or solutions.

Okay, having reached this point, the problem is now sharply defined enough to create an issue and ask a question directly. If searching hasn't yielded a solution, post the question. Depending on the urgency or importance of this issue, you might just wait, or you might look for other solutions. For now, let's assume the situation requires a resolution as quickly as possible and move on. (Fortunately, in A's case, replacing the plugin solved the problem).

5. Direct Resolution

Reaching this stage is often the most challenging, I think. The problem has been narrowed down to a specific API within a specific plugin, and a detailed question has been posted somewhere reliable. But you can't just wait indefinitely. You need to fix the problematic code yourself. This process can also present an opportunity to contribute to open source. Looking directly at open-source code might seem daunting, but if the problem is well-defined and you're somewhat familiar with the framework, it's often surprisingly manageable. Discovering and fixing something like an incorrect conditional statement in a specific function line is often achievable. Bugs are frequently that simple; nothing extraordinary. Even if it's not a simple bug and requires significant changes or feature additions, I recommend trying to implement it yourself and submitting a Pull Request rather than just requesting the work be done. It's an excellent opportunity to build your open-source portfolio while doing your company work.

If, after examining the code and trying various approaches, you determine you cannot resolve it directly due to a lack of domain knowledge, well... having come this far, you might genuinely consider changing, removing, or postponing the specification. At least until this problem is resolved. The important thing is that because you've come this far, giving up is a valid option. The reasons are sufficient. If, in the actual scenario, the issue had involved something more critical than a favicon plugin and we had reached this point, we would likely have postponed the framework migration for the time being. Going through this entire process is what it means to fail correctly.

Conclusion

Some readers might think, "This is so obvious, why explain it in such detail?" while others might think, "Do we really need to go to such lengths?" But yes, you do need to go to these lengths. I wrote this down because it's often the case that people don't do this because they don't know how, rather than because they choose not to. Frankly, I'm tired of explaining it repeatedly. From now on, I plan to just share this article. :)

♥ Support writer ♥
with kakaopay

Creative Commons LicenseThis work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.

shiren • © 2025Sungho Kim