views:

73

answers:

3

Here's the relevant code:

Public class User.cs:

public void FindByID(int id)
        {
            Parser parser = new Parser(id);

            ID = parser.FindID();
            Name = parser.FindName();
            Rating = parser.FindRating();
            Photo = parser.FindPhoto();
            Reputation = parser.FindReputation();
            Group = parser.FindGroup();
            PostCount = parser.FindPosts();
            PostPerDay = parser.FindPostsPerDay();
            JoinDate = parser.FindJoinDate();
            Views = parser.FindViews();
            LastActive = parser.FindLastActive();
            Title = parser.FindTitle();
            Age = parser.FindAge();
            Birthday = parser.FindBirthday();
            Sex = parser.FindSex();
        }

Public class Parser.cs:

public Parser(int userID)
        {
            doc = XDocument.Load(String.Format("http://www.dreamincode.net/forums/xml.php?showuser={0}", userID));            
        }

        /***********************************************************
         * Methods that scrape information individually for fields *
         * ********************************************************/

        public string FindID()
        {
            return doc.XPathSelectElement("/ipb/profile/id").Value;
        }

        public string FindName()
        {
            return doc.XPathSelectElement("/ipb/profile/name").Value;
        }

        /etc etc etc

If I try to search for a user that doesn't exist I get an exception thrown because doc is never initialized. I'm not sure where I should catch this bug. Maybe the way I've done things have put me in this position.

I'd like to learn. :P Thanks!

Edit: Here's the Stacktrace:

   at DICHeads.Parser.FindID() in c:\users\sergio\documents\visual studio 2010\Projects\DICHeads\DICHeads\Parser.cs:line 36
   at DICHeads.User.FindByID(Int32 id) in c:\users\sergio\documents\visual studio 2010\Projects\DICHeads\DICHeads\User.cs:line 33
   at DICHeads.MainWindow.button1_Click(Object sender, RoutedEventArgs e) in c:\users\sergio\documents\visual studio 2010\Projects\DICHeads\DICHeads\MainWindow.xaml.cs:line 36
   at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
   at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
   at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
   at System.Windows.UIElement.RaiseEvent(RoutedEventArgs e)
   at System.Windows.Controls.Primitives.ButtonBase.OnClick()
   at System.Windows.Controls.Button.OnClick()
   at System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs e)
   at System.Windows.UIElement.OnMouseLeftButtonUpThunk(Object sender, MouseButtonEventArgs e)
   at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
   at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
   at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
   at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
   at System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent)
   at System.Windows.UIElement.CrackMouseButtonEventAndReRaiseEvent(DependencyObject sender, MouseButtonEventArgs e)
   at System.Windows.UIElement.OnMouseUpThunk(Object sender, MouseButtonEventArgs e)
   at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
   at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
   at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
   at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
   at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
   at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted)
   at System.Windows.Input.InputManager.ProcessStagingArea()
   at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
   at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
   at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel)
   at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Boolean isSingleParameter)
   at System.Windows.Threading.Dispatcher.Invoke(DispatcherPriority priority, Delegate method, Object arg)
   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
   at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
   at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
   at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
   at System.Windows.Threading.Dispatcher.Run()
   at System.Windows.Application.RunDispatcher(Object ignore)
   at System.Windows.Application.RunInternal(Window window)
   at System.Windows.Application.Run(Window window)
   at System.Windows.Application.Run()
   at DICHeads.App.Main() in c:\users\sergio\documents\visual studio 2010\Projects\DICHeads\DICHeads\obj\x86\Debug\App.g.cs:line 0
   at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
   at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
   at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()
A: 

There are two ways you can handle it.

  1. You can add a check the constructor to see if doc has been populated. If not create a new default instance so all your code will still work but not return any results. Though once outside of the constructor you can wrap the following code with an if to check whether in fact the doc was loaded.

  2. You can skip the default instance and just check the doc outside the constructor like you were in the first solution.

spinon
+1  A: 

The way I would do it:

  1. Throw a no-such-user exception (or similar) from the constructor if the user doesn't exist.
  2. Wrap the constructor call in a try-catch block.
Anon.
+1  A: 

Your code could can throw a NullReferenceException because XPathSelectElement returns null if the element is not found.

Return Value
Type: System.Xml.Linq.XElement
An XElement, or null.

Change your code to this:

public string FindID()
{ 
    var element = doc.XPathSelectElement("/ipb/profile/id");
    if (element == null) { return null; }
    return element.Value;
}

And similarly for your other methods.

Mark Byers