Repository: CiviWiki/OpenCiviWiki

Issue:
Don't use general Exception class to catch exceptions 
`except Exception as e` is usually not considered a good practice.

https://github.com/CiviWiki/OpenCiviWiki/blob/aa44eeb0e90944a229dc2fa35e83925c97e40e41/project/accounts/authentication.py#L165-L166

https://github.com/CiviWiki/OpenCiviWiki/blob/aa44eeb0e90944a229dc2fa35e83925c97e40e41/project/accounts/authentication.py#L233-L234

Maybe these should be catching some specific Exceptions
Don't use general Exception class to catch exceptions 
`except Exception as e` is usually not considered a good practice.

https://github.com/CiviWiki/OpenCiviWiki/blob/aa44eeb0e90944a229dc2fa35e83925c97e40e41/project/accounts/authentication.py#L165-L166

https://github.com/CiviWiki/OpenCiviWiki/blob/aa44eeb0e90944a229dc2fa35e83925c97e40e41/project/accounts/authentication.py#L233-L234

Maybe these should be catching some specific Exceptions


Discussion:
@dummy26  
Can I take this up?
Sure!
@calicomills, thanks for your help. I've assigned you to the issue.
@brylie @dummy26 I think many actual errors can go hidden using the general` Exception` class, I think we should have separate custom `Exception` classes and `raise` custom exceptions when we encounter something wrong, and consequently ditch the try/except block.

Something like this,

```
class AccountCreationError(Exception):
       def __init__(self, *args):
            if args:
                self.msg = args[0]
            else:
                self.message = None

      def __str__(self):
          if self.msg:
              return f'AccountCreationError, {self.msg} '
          else:
              return 'AccountCreationError has been raised'
```


 @calicomills looks good. That way it would be descriptive.
> @calicomills looks good. That way it would be descriptive.

OK..I will start working on this.
@dummy26  
Can I take this up?
Sure!
@calicomills, thanks for your help. I've assigned you to the issue.
@brylie @dummy26 I think many actual errors can go hidden using the general` Exception` class, I think we should have separate custom `Exception` classes and `raise` custom exceptions when we encounter something wrong, and consequently ditch the try/except block.

Something like this,

```
class AccountCreationError(Exception):
       def __init__(self, *args):
            if args:
                self.msg = args[0]
            else:
                self.message = None

      def __str__(self):
          if self.msg:
              return f'AccountCreationError, {self.msg} '
          else:
              return 'AccountCreationError has been raised'
```


 @calicomills looks good. That way it would be descriptive.
> @calicomills looks good. That way it would be descriptive.

OK..I will start working on this.

Resolving patch:
diff --git a/project/api/read.py b/project/api/read.py
--- a/project/api/read.py
+++ b/project/api/read.py
@@ -34,6 +34,8 @@ def get_card(request, user):
             a, Account.objects.get(user=request.user)
         )
         return JsonResponse(result)
+    except User.DoesNotExist:
+        return HttpResponseBadRequest(reason=f"User with username {user} not found")
     except Account.DoesNotExist as e:
         return HttpResponseBadRequest(reason=str(e))
     except Exception as e:
@@ -168,6 +170,10 @@ def get_thread(request, thread_id):
         t.save()
 
         return json_response(data)
+    except Thread.DoesNotExist:
+        return HttpResponseBadRequest(reason=f"Thread with id:{thread_id} does not exist")
+    except Account.DoesNotExist:
+        return HttpResponseBadRequest(reason=f"Account with username:{request.user.username} does not exist")
     except Exception as e:
         return HttpResponseBadRequest(reason=str(e))
 
@@ -215,5 +221,9 @@ def get_responses(request, thread_id, civi_id):
         civis = sorted(c_scored, key=lambda c: c["score"], reverse=True)
 
         return JsonResponse(civis, safe=False)
+    except Account.DoesNotExist:
+        return HttpResponseBadRequest(reason=f"Account with user:{request.user.username} does not exist")
+    except Civi.DoesNotExist:
+        return HttpResponseBadRequest(reason=f"Civi with id:{civi_id} does not exist")
     except Exception as e:
         return HttpResponseBadRequest(reason=str(e))
diff --git a/project/api/write.py b/project/api/write.py
--- a/project/api/write.py
+++ b/project/api/write.py
@@ -59,6 +59,8 @@ def new_thread(request):
         new_t.save()
 
         return JsonResponse({"data": "success", "thread_id": new_t.pk})
+    except Account.DoesNotExist:
+        return HttpResponseServerError(reason=f"Account with user:{request.user.username} does not exist")
     except Exception as e:
         return HttpResponseServerError(reason=str(e))
 
@@ -272,6 +274,8 @@ def editThread(request):
                 setattr(req_edit_thread, param, request_value)
 
         req_edit_thread.save()
+    except Thread.DoesNotExist:
+        return HttpResponseServerError(reason=f"Thread with id:{thread_id} does not exist")
     except Exception as e:
         return HttpResponseServerError(reason=str(e))
 
@@ -357,6 +361,11 @@ def uploadProfileImage(request):
 
                 response = {"profile_image": account.profile_image_url}
                 return JsonResponse(response, status=200)
+
+            except Account.DoesNotExist:
+                response = {"message": f"Account with user {request.user.username} does not exist",
+                            "error": "ACCOUNT_ERROR"}
+                return JsonResponse(response, status=400)
             except Exception as e:
                 response = {"message": str(e), "error": "MODEL_ERROR"}
                 return JsonResponse(response, status=400)
@@ -380,6 +389,8 @@ def clearProfileImage(request):
             account.save()
 
             return HttpResponse("Image Deleted")
+        except Account.DoesNotExist:
+            return HttpResponseServerError(reason=f"Account with id:{request.user.username} does not exist")
         except Exception:
             return HttpResponseServerError(reason=str("default"))
     else:
@@ -420,6 +431,8 @@ def uploadCiviImage(request):
             }
             return JsonResponse(data)
 
+        except Civi.DoesNotExist:
+            return HttpResponseServerError(reason=f"Civi with id:{civi_id} does not exist")
         except Exception as e:
             return HttpResponseServerError(
                 reason=(str(e) + civi_id + str(request.FILES))
@@ -474,6 +487,8 @@ def uploadThreadImage(request):
             data = {"image": thread.image_url}
             return JsonResponse(data)
 
+        except Thread.DoesNotExist:
+            return HttpResponseServerError(reason=f"Thread with id:{thread_id} does not exist")
         except Exception as e:
             return HttpResponseServerError(reason=(str(e)))
     else:
@@ -537,15 +552,21 @@ def requestUnfollow(request):
     :return: (200, okay, list of friend information) (400, bad lookup) (500, error)
     """
     try:
-        account = Account.objects.get(user=request.user)
-        target = User.objects.get(username=request.POST.get("target", -1))
-        target_account = Account.objects.get(user=target)
+        username = request.POST.get("target")
+        if username:
+            account = Account.objects.get(user=request.user)
+            target = User.objects.get(username=username)
+            target_account = Account.objects.get(user=target)
 
-        account.following.remove(target_account)
-        account.save()
-        target_account.followers.remove(account)
-        target_account.save()
-        return JsonResponse({"result": "Success"})
+            account.following.remove(target_account)
+            account.save()
+            target_account.followers.remove(account)
+            target_account.save()
+            return JsonResponse({"result": "Success"})
+        return HttpResponseBadRequest(reason=f"username cannot be empty ")
+
+    except User.DoesNotExist:
+        return HttpResponseBadRequest(reason=f"User with username {username} does not exist")
     except Account.DoesNotExist as e:
         return HttpResponseBadRequest(reason=str(e))
     except Exception as e:


Test patch: