When to use Exception - exception

I have a Form or Page and some privileges (Save, Modify, Delete etc.) assigned to a user that is using this page, let's assume this user only has Save and Modify privileges.
When user clicks Delete button, which he is not privileged to, I want to display a message to him to inform him that he doesnt have this privilege, how should my code look like?
Option 1
If(loggedUser.Privileges.Contains(PrivilegeTypes.Delete) == false)
{
MessageBox.Show("You dont have delete privilege!");
// Log that user tried to delete without permission etc
return;
}
Option 2
try
{
If(loggedUser.Privileges.Contains(PrivilegeTypes.Delete) == false)
{
// Throw custom exception
throw new UngrantedPrivilegeException(PrivilegeTypes.Delete, "Invalid privilege exception");
}
}
catch (UngrantedPrivilegeException ex)
{
if( ex.PrivilegeType == PrivilegeTypes.Delete)
{
MessageBox.Show("You dont have delete privilege!");
// Log that user tried to delete without permission etc
}
}

In this case i would go for first option since i know what are the possibilities and no need of creating unwanted exception object as burden on memory.
Exception should be used to handle unknown run time errors, not for logic conditions.

There is absolutely no reason to use an exception in this case. There is nothing exceptional about what the code is doing, and simple conditional logic is appropriate.
Consider the semantic logic of your first option:
Does the user have permission?
Tell the user they don't have permission.
Now consider the semantic logic of your second option:
Try to check for permission
Does the user have permission?
The user does not have permission.
Did the user have permission?
Tell the user they don't have permission.
Seems like a lot of redundancy in the second one, don't you think? You're also adding more overhead to the runtime by throwing an exception for the sole purpose of immediately handling it, when all you really wanted to do was check a condition. if statements exist to check conditions, there's no reason not to use one here. (Indeed, you are using one even in your second example.) It also pollutes the code with a lot of unnecessary things which distract from the basic business logic of what you're doing (checking a permission setting), making the code more difficult to support.
Don't use exceptions for logic flow. Use them to handle unexpected things that shouldn't happen, not to determine the logic flow of things that are expected to happen.

Related

Reason for failure in MultipartObjectAssembler OCI object storage

I'm using MultipartObjectAssembler to upload data from a Database to OCI object storage.
Is there a way to know the reason for failure when using multipart upload?
When I try to commit assembler I'm getting IllegalStateException with the message "One or more parts were have not completed upload successfully".
I would like to know why any part got failed? I couldn't find a way to get this information from SDK.
try {
assembler.addPart(new ByteArrayInputStream(part, 0, length),
length,
null);
assembler.commit();
} catch (Exception e) {
assembler.abort();
throw new RuntimeException(e.getMessage());
}
Edit: I need to get an Exception thrown by a failed part and propagate the error message.
Is there a reason you are not using the UploadManager? It should do everything for you, including adding parts and committing. Here's an end-to-end example: https://github.com/oracle/oci-java-sdk/blob/master/bmc-examples/src/main/java/UploadObjectExample.java
If, for some reason, you cannot use UploadManager, please take a look at its source code nonetheless, since it demonstrates the intended usage of MultipartObjectAssembler: https://github.com/oracle/oci-java-sdk/blob/master/bmc-objectstorage/bmc-objectstorage-extensions/src/main/java/com/oracle/bmc/objectstorage/transfer/UploadManager.java#L175-L249
You create the MultipartObjectAssembler:
MultipartObjectAssembler assembler =
createAssembler(request, uploadRequest, executorServiceToUse);
You create a new request. This gives you back a MultipartManifest, which will later let you check if parts failed.
manifest =
assembler.newRequest(
request.getContentType(),
request.getContentLanguage(),
request.getContentEncoding(),
request.getOpcMeta());
Then you add all the parts:
assembler.addPart(
ProgressTrackingInputStreamFactory.create(
chunk, progressTrackerFactory.getProgressTracker()),
chunk.length(),
null);
Then you commit. This is where your code currently throws. I suspect not all parts have been added.
CommitMultipartUploadResponse response = assembler.commit();
If something goes wrong, check MultipartManifest.listCompletedParts(), MultipartManifest.listFailedParts(), and MultipartManifest.listInProgressParts(). The manifest should tell you what parts failed. Unfortunately not why; for that, you can enable ERROR level logging for com.oracle.bmc.objectstorage.transfer (for the class com.oracle.bmc.objectstorage.transfer.internal.MultipartTransferManager in particular).
If I have misunderstood something, please let me know. In that case, a larger, more complete code snippet would help me debug. Thanks!

Restrict feathers service method to user for external but allow any queries for internal calls

I want to restrict calls to a Feathers service method for externals calls with associateCurrentUser.
I also want to allow the server to call this service method without restricting it.
The use case is that through this service then clients use a lock table, all clients can see all locks, and occasionally the server should clear out abandoned rows in this table. Row abandonment can happen on network failures etc. When the server removes data then the normal Feathers remove events should be emitted to the clients.
I would imagine that this should be a mix of associateCurrentUser and disallow hooks but I can't even begin to experiment with this as I don't see how it would be put together.
How would one implement this, please?
Update:
I found this answer User's permissions in feathers.js API from Daff which implies that if the hook's context.params.provider is null then the call is internal, otherwise external. Can anyone confirm if this is really so in all cases, please?
It seems to be so from my own tests but I don't know if there are any special cases out there that might come and bite me down the line.
If the call is external params.provider will be set to the transport that has been used (currently either rest, socketio or primus, documented here, here and here).
If called internally on the server there is not really any magic. It will be whatever you pass as params. If you pass nothing it will be undefined if you pass (or merge with) hook.params in a hook it will be the same as what the original method was called with.
// `params` is an empty object so `params.provider` will be `undefined`
app.service('messages').find({})
// `params.provider` will be `server`
app.service('messages').find({ provider: 'server' })
// `params.provider` will be whatever the original hook was called with
function(hook) {
hook.app.service('otherservice').find(hook.params);
}

Uninstalling UserPassChange script

I installed a script http://www.googleappsscript.org/home/force-google-apps-users-to-change-password-periodically. Idea was to force Google Apps - users in my organisation to change their passwords every 3 months. Script works well. However, there are certain accounts whose password must remain the same and therefore I would need to uninstall the script.
Would anyone be able to help me out?
Thanks in advance.
An alternative method would be to add 3 exceptions to this list using an IF/ELSE statement, and a method to ignore the 3 users. I'll provide you with an example in C#, since that's the language I'm most fluent in:
if (username == "VIP1")
{ ignore(string username)}
else if (username == "VIP2")
{ ignore(string username)}
else if (username == "VIP3")
{ ignore(string username)}
else
{ passchange()}
You'd also need to provide an overload for the user in the ignore() method. If you have a relatively small userbase (under, say, 200 users), this idea would be very effective. If you have a larger userbase, this may be a bit of an expensive process, since you have to run through the entire userlist for each iteration of the if/else statement.
Users that installed the script and authorized it have received an email with uninstall instruction. This message shows a link to uninstall the script, this link is easy to re-build if ever they lost it :
use the link of the script and replace the ending part with /manage/uninstall.
for example, this script url
https://script.google.com/d/1DsMPFCPo-870TuOFM4Sg9BY0c28gyj8NY_________n0upV1AOG2MAsxy/edit?usp=drive_web
would be changed to
https://script.google.com/d/1DsMPFCPo-870TuOFM4Sg9BY0c28gyj8NY_________n0upV1AOG2MAsxy/manage/uninstall
that will direct the user to a page looking like this :

DDD: can a repository return boolean values?

Is it ok for a Repository to return boolean values based on objects it (virtually) contains?
For example:
if (userRepository.checkCredentials(username, password))
{
// ...
Or is it a better approach to do it the verbose way:
user = userRepository.findByUsername(username);
if (user != null && user.checkPassword(password)) {
{
// ...
Sounds more like a specification doesn't it?
if (canAuthenticateSpec.isSatisfiedBy(username, password))
In the past, I have done this with a specification, so I can clearly and simply have that check around for my code to use.
But, recently, I did this with a service that does the work, and builds a result based on why they didn't authenticate. So, something, like this:
AuthenticateResult result = slAuthenticator.Authenticate(username, password)
if (result.authenticated) {
user = result.user
} else {
String message = result.failureReason;
A Repository is a mechanism for encapsulating storage, retrieval, and
search behavior which emulates a collection of objects.
I think it is OK to return boolean from a repository but only if the method involves all the objects in this repository. Repository usually exposes collection-like interface. For example users.IsEmpty() or users.IsNameUnique("jdoe") seem logical because they need access to the whole collection.
In your scenario, only finding user by name is the responsibility that can be assigned to the repository. Checking whether password is valid or not does not seem like a good fit for repository. So the second, more verbose, approach seems better to me.
Alternatively you can have a dedicated Authenticator interface in your domain and implementation in data access layer (similarly to how repositories are implemented). Or Authenticator can become a domain service that uses repository internally. Authenticator can also tell between 'user not found' or 'password invalid' which would probably have different business meaning.

sfErrorNotifierPlugin: The "default" context does not exist

I have installed the sfErrorNotifierPlugin. When both options reportErrors/reportPHPErrors reportPHPWarnings/reportWarnings are set to false, everything is ok. But I want to catch PHP exceptions and warnings to receive E-mails, but then all my tasks fail, including clear-cache. After few hours of tests I'm 100% sure that the problem is with set_exception_handler/set_error_handler.
There's a similar question:
sfErrorNotifierPlugin on symfony task but the author there is having problems with a custom task. In my case, even built-in tasks fail.
I haven't used sfErrorNotifierPlugin, but I have run into 'The “default” context does not exist.' messages before. It happens when a call is made to sfContext::getInstance() and the context simply doesn't exist. I've had this happen a lot from within custom tasks. One solution is to add sfContext::createInstance() before the call to sfContext::getInstance(). This will ensure that a context exists.
There's an interesting blog post on 'Why sfContext::getInstance() is bad' that goes into more detail - http://webmozarts.com/2009/07/01/why-sfcontextgetinstance-is-bad/
Well, the problem could not be solved this way, unfortunately. Using sfErrorNotifierPlugin, I have enabled reporting PHP warning/errors (apart from symfony exceptions) and this resulted in huge problems, e.g. built-in tasks such as clear-cache failed.
The solution I chose was to load the plugin only in non-task mode (project configuration class):
public function setup()
{
$this->enableAllPluginsExcept('sfPropelPlugin');
if ('cli' == php_sapi_name()) $this->disablePlugins('sfErrorNotifierPlugin');
}
WHen a task is executed, everything works normally. When an app is fired from the browser, emails are sent when exception/warning occurs (maybe someone will find it useful).
Arms has explained the problem correctly. But usually context does not exist when executing backend/maintenance tasks on the console. And it is easier if you handle the condition yourself.
Check, if you really need the context?
If you do, what exactly do you need it for?
Sometimes you only want a user to populate a created_by field. You can work around by hard-coding a user ID.
If you want to do something more integrated, create a page (which will have a context) and trigger the task from there.
you can test the existance of the instance before doing something inside a class. Like:
if(sfContext::hasInstance())
$this->microsite_id = sfContext::getInstance()->getUser()->getAttribute('active_microsite');
I've been experiencing the same problem using the plugin sfErrorNotifier.
In my specific case, I noticed a warning was raised:
Warning: ob_start(): function '' not found or invalid function name in /var/www/ncsoft_qa/lib/vendor/symfony/lib/config/sfApplicationConfiguration.class.php on line 155
Notice: ob_start(): failed to create buffer in /var/www/ncsoft_qa/lib/vendor/symfony/lib/config/sfApplicationConfiguration.class.php on line 155
So, checking the file: sfApplicationConfiguration.class.php class, line 155,
I've replaced the ' ' for a null, then the warnings disappears, and also the error!
ob_start(sfConfig::get('sf_compressed') ? 'ob_gzhandler' : ''); bad
ob_start(sfConfig::get('sf_compressed') ? 'ob_gzhandler' : null); good